【问题标题】:Long running ProgressDialog shows Application not responding (ANR) dialog长时间运行 ProgressDialog 显示应用程序无响应 (ANR) 对话框
【发布时间】:2012-02-05 00:36:34
【问题描述】:

您好,我目前正在开发一个应用程序,该应用程序在首次启动时需要非常大的下载量 (100-200MB)。

我的第一个活动启动了一个服务,它有一个异步任务来完成所有下载。

为了显示我的下载进度,我正在执行以下操作:

首先使用 AsyncTask 的 publishProgress/onProgressUpdate 我向我的活动发送当前进度的广播:

@Override
protected Void doInBackground(Void... params) { 
  ...
  publishProgress(Integer.toString(completedFiles), current_filename, Integer.toString(file_progress));
  ...
}
@Override
protected void onProgressUpdate(String... progress) {
        super.onProgressUpdate(progress);
        progressBroadcast.putExtra(NOTIFY_DOWNLOAD_PROGRESS, progress);
        sendOrderedBroadcast(progressBroadcast, null);
}

在我的活动中,我有一个更新进度条的 BroadcastReceiver

    private class ProgressReceiver extends BroadcastReceiver{

    private int totalFiles;

    public ProgressReceiver(Context context) {
        progressDialog = new ProgressDialog(context);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if(ResourceDownloadService.NOTIFY_DOWNLOAD_START.equals(action)){               
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.setCancelable(false);
            progressDialog.setTitle(getString(R.string.loading_res_dialog_title));
            totalFiles = intent.getIntExtra(ResourceDownloadService.TOTAL_FILES, 0);
            progressDialog.setMessage("Downloading Resources");
            progressDialog.show();
        }else if(ResourceDownloadService.NOTIFY_DOWNLOAD_END.equals(action)){
            //Hide progress bar one we are done
            progressDialog.dismiss();
            startIntroActivity();
        }else{
            String[] progress_info = intent.getExtras().getStringArray(ResourceDownloadService.NOTIFY_DOWNLOAD_PROGRESS);
            int completedFiles = Integer.parseInt(progress_info[0]);
            String filename = progress_info[1];
            int progress = Integer.parseInt(progress_info[2]);
            progressDialog.setProgress(progress);
            progressDialog.setMessage("Downloading "+filename +"\n"+completedFiles +" files downloaded of "+totalFiles);
        }
    }

}

所以我不确定我在这里做错了什么,因为在进度条显示几秒钟后,我得到了 ANR。

可能是因为我发送了太多的广播来更新进度条??

【问题讨论】:

  • .....100-200MB,这太疯狂了,但除了为什么要使用广播接收器来执行此操作之外,AsyncTask 的 publishProgess 方法专门设计用于从后台线程更新 UI 跨度>
  • 我知道,但我看到市场上很多游戏都是这样做的,而且它只会在应用程序的首次启动时出现。我将进度作为广播发送,因为我在 Service 中使用 AyncTask 然后向活动发送广播,所以如果活动不存在(配置更改),服务无论如何都会下载资源

标签: android service android-asynctask


【解决方案1】:

我唯一能想到的是 ANR 是由于进度对话框长时间禁用交互,请尝试删除对话框并使用其他方法通知用户进度。

类似的东西

public interface Listener {

    public abstract void onEvent();

}

在广播接收器中创建静态引用和设置器

私有静态 MessageListener mListener = null;

@Override
public void onReceive(Context context, Intent intent) {
    //stuff
    if(mListener != null)
         mListener.onEvent();   
}

public static void setListener(Listener l) {
    mListener = l;
}

然后在Activity中实现监听器

class MyActivity implements Listener{

@Override
public void onResume(){
    //register the listener so that when the activity is visible it can receive updates
    BroadCastReceiver.setListener(this);
}

@Override
public void onPause(){
    //unregister the listener so the activity doesn't receive updates while in the background
    BroadCastReceiver.setListener(null);
}
@Override
public void onEvent(){
    //update the UI
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    相关资源
    最近更新 更多