Индикатор выполнения не отображается при выполнении AsyncTask

#android #android-asynctask

#Android #android-asynctask

Вопрос:

Я пытаюсь показать диалоговое окно выполнения во время загрузки моего ListView (чтобы показать все приложения на устройстве).

но он не отображается.

вот мой основной класс activity и то, что я пробовал.

в чем может быть проблема?

 public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment())
                .commit();
    }


}


ProgressDialog dlg;
private class Updator extends AsyncTask<Void, Void, Void> 
{ 
    public Updator()
    {
        dlg = new ProgressDialog(MainActivity.this);
        dlg.setMessage("Text");
        dlg.setTitle("Title");
    }

    @Override
    protected void onPreExecute() 
    {
        dlg.show();
    }

    protected Void doInBackground(Void... unused) {
        runOnUiThread(new Runnable() {
            public void run() 
            {
                PackageManager pm = getPackageManager();
                List<ApplicationInfo> apps = pm.getInstalledApplications(0);
                ArrayList<ApplicationInfo> installedApp = new ArrayList<ApplicationInfo>();


                for(ApplicationInfo app : apps) 
                {
                    installedApp.add(app);
                }

                ListView lv = (ListView) findViewById(R.id.listView1);


                //custom list is a class to create a custom list view.
                //it also will load application icons into list(which needs time)
                CustomList adapter = new CustomList(MainActivity.this, installedApp);

                TextView t = (TextView) findViewById(R.id.textView1);
                t.setText(installedApp.size());

                lv.setAdapter(adapter);

                lv.setOnItemClickListener(new AdapterView.OnItemClickListener() 
                {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
                    {
                       //some things app will do
                    }
                });
            }
        });
        return (null);
    }

    protected void onPostExecute(Void unused) 
    {

        dlg.dismiss();
    }
}


public void onBtnClick(View v)
{
    new Updator().execute();
}
  

}

Комментарии:

1. Вам не нужен runOnUiThread в doInBackground

2. @Raghunandan В этом случае я получу сообщение об ошибке ‘lv.setAdapter (адаптер);’

3. Предполагается, что doInBackground предназначен для фоновой работы. У вас есть onPostExecute, где вы можете выполнить операцию пользовательского интерфейса.

Ответ №1:

Вероятно, вам следует изменить свою asynctask, чтобы она выглядела примерно так:

 private class Updator extends AsyncTask<Void, Void, ArrayList<ApplicationInfo>> {

public Updator()
{
    dlg = new ProgressDialog(MainActivity.this);
    dlg.setMessage("Text");
    dlg.setTitle("Title");
}

@Override
protected void onPreExecute()
{
    dlg.show();
}

@Override
protected ArrayList<ApplicationInfo> doInBackground(Void... params) {
    PackageManager pm = getPackageManager();
    List<ApplicationInfo> apps = pm.getInstalledApplications(0);
    ArrayList<ApplicationInfo> installedApp = new ArrayList<ApplicationInfo>();


    for(ApplicationInfo app : apps)
    {
        installedApp.add(app);
    }

    return installedApp;
}

@Override
protected void onPostExecute(ArrayList<ApplicationInfo> installedApps) {
    ListView lv = (ListView) findViewById(R.id.listView1);

    //custom list is a class to create a custom list view.
    //it also will load application icons into list(which needs time)
    CustomList adapter = new CustomList(MainActivity.this, installedApp);

    TextView t = (TextView) findViewById(R.id.textView1);
    t.setText(installedApp.size());

    lv.setAdapter(adapter);

    lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id)
        {
            //some things app will do
        }
    });

    dlg.dismiss();
}
}
  

Если вы выполните все вычисления в doInBackground в главном потоке, он не покажет счетчик.
Как указано в некоторых комментариях, лучше выполнять вычисления в фоновом режиме, а затем отправлять эту информацию в onPostExecute.