【问题标题】:Circle progress bar while AsyncTask is executed: Error执行 AsyncTask 时圈出进度条:错误
【发布时间】:2013-11-05 17:10:50
【问题描述】:

我需要在异步任务运行时向用户显示微调器:

public class RecoverListTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog spinner;
private Context context;

public RecoverListTask(Context c) {
    context = c;
    spinner = new ProgressDialog(context); // spinner
}

@Override
protected void onPreExecute() {
    // show progress spinner
    spinner.setMessage("Downloading Podcats List");
    spinner.show();

        //do something
}

    @Override
protected void onPostExecute(Void v) {
    spinner.dismiss();
}
}

(我只粘贴了关于微调器的部分)但是当我尝试运行应用程序时,我遇到了这个错误:

11-05 18:02:49.077: E/WindowManager(28986): Activity com.example.podcast610downloader.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{4264ef28 V.E..... R....... 0,0-684,192} that was originally added here
11-05 18:02:49.077: E/WindowManager(28986): android.view.WindowLeaked: Activity com.example.podcast610downloader.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{4264ef28 V.E..... R....... 0,0-684,192} that was originally added here
11-05 18:02:49.077: E/WindowManager(28986):     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:345)
11-05 18:02:49.077: E/WindowManager(28986):     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:239)
11-05 18:02:49.077: E/WindowManager(28986):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
11-05 18:02:49.077: E/WindowManager(28986):     at android.app.Dialog.show(Dialog.java:281)
11-05 18:02:49.077: E/WindowManager(28986):     at com.example.podcast610downloader.RecoverListTask.onPreExecute(RecoverListTask.java:31)
11-05 18:02:49.077: E/WindowManager(28986):     at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
11-05 18:02:49.077: E/WindowManager(28986):     at android.os.AsyncTask.execute(AsyncTask.java:534)
11-05 18:02:49.077: E/WindowManager(28986):     at com.example.podcast610downloader.MainActivity.onCreate(MainActivity.java:24)
11-05 18:02:49.077: E/WindowManager(28986):     at android.app.Activity.performCreate(Activity.java:5133)
11-05 18:02:49.077: E/WindowManager(28986):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
11-05 18:02:49.077: E/WindowManager(28986):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
11-05 18:02:49.077: E/WindowManager(28986):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
11-05 18:02:49.077: E/WindowManager(28986):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-05 18:02:49.077: E/WindowManager(28986):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
11-05 18:02:49.077: E/WindowManager(28986):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-05 18:02:49.077: E/WindowManager(28986):     at android.os.Looper.loop(Looper.java:137)
11-05 18:02:49.077: E/WindowManager(28986):     at android.app.ActivityThread.main(ActivityThread.java:5103)
11-05 18:02:49.077: E/WindowManager(28986):     at java.lang.reflect.Method.invokeNative(Native Method)
11-05 18:02:49.077: E/WindowManager(28986):     at java.lang.reflect.Method.invoke(Method.java:525)
11-05 18:02:49.077: E/WindowManager(28986):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-05 18:02:49.077: E/WindowManager(28986):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-05 18:02:49.077: E/WindowManager(28986):     at dalvik.system.NativeStart.main(Native Method)

关于创建代码:

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

    //recover list of available podcast (with details)
    RecoverListTask task = new RecoverListTask(this);
    task.execute(null, null, null);

    listView = (ListView) findViewById(R.id.listView);
    arrayAdapter=new ArrayAdapter<PodcastFile>(this, android.R.layout.simple_list_item_1);
    listView.setAdapter(arrayAdapter);
    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            // TODO Auto-generated method stub

        }

    });

}

有什么问题?

【问题讨论】:

  • 显示你的 asyntask 的 doInbackground
  • doInBackGround 只需从服务器下载文件并保存到存储中
  • 我不这么认为这太简单了..可能是您在 DOIN 中的 UI 更新..
  • 在 doInBackGround 中没有修改 UI 元素。只需下载文件并保存到文件夹

标签: android android-asynctask android-progressbar


【解决方案1】:

我认为在实例化 Asynctask 时,您正在通过 getApplicationContext() 传递上下文

new RecoverListTask(getApplicationContext()).execute();

试着这样做

 new RecoverListTask(MainActivity.this).execute();

检查它是否有效!

【讨论】:

  • 我得到了同样的异常
【解决方案2】:

不要保留对上下文变量的引用。这显然是无用的,这就是保留您的活动实例的原因。

只需删除这些行:

private Context context;
context = c;

EDIT___________

好的,我会这样做:

public class MainActivity extends Activity
{
    private ProgressDialog  spinner;

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

        spinner = new ProgressDialog(this);

        // show progress spinner
        spinner.setMessage("Downloading Podcats List");
        spinner.show();

        // recover list of available podcast (with details)
        RecoverListTask task = new RecoverListTask();
        task.execute(null, null, null);
    }

    private void onLoadingComplete()
    {
        spinner.dismiss();
    }

    public class RecoverListTask extends AsyncTask<Void, Void, Void>
    {
        public RecoverListTask()
        {}

        @Override
        protected void onPreExecute()
        {

        }

        @Override
        protected void onPostExecute(Void v)
        {
            onLoadingComplete();
        }

        @Override
        protected Void doInBackground(Void... params)
        {
            // do something

            //If you want to get a reference to the Activity use 
            //MainActivity.this instead of context

            return null;
        }
    }
}

【讨论】:

  • 但是这个类不是一个活动,它是一个 AsyncTask,我需要一个对调用者活动的引用!
  • 我知道这不是一个活动,但是这个 AsyncTask 在必须销毁它时保留对您的活动(上下文变量)的引用,例如在onPostExecute() 之后。所以你必须摆脱引用,你可以尝试onPostExecute()方法中的context = null;,但是如果你的activity在AsyncTask完成它的任务之前就被销毁了,那么你会遇到同样的错误。
  • Activity 在执行该 asynctask 期间无法销毁,因为 asynctask 的执行是在 MainActivity 的 onCreate() 内部开始的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多