当从 Asynctask 更新通知进度条时,应用程序可能在其主线程上做了太多工作
The application may be doing too much work on its main thread while update notification progress bar from Asynctask
我创建了一个从前台服务下载文件并在通知进度条中显示下载进度的演示。我在服务中使用 asynctask,在 asynctask 中我使用 HttpUrlConnection 从 Internet 下载文件并更新 onProgressUpdate() 中的进度。我显示以下错误
跳过了 145 帧!应用程序可能在其主线程上做了太多工作。
和phone被绞死。
Service.java
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG + "===", "onStartCommand");
String downloadUrl = "", downloadFileName = "";
Bundle bundle = intent.getExtras();
if (bundle != null) {
downloadUrl = bundle.getString("download_url");
downloadFileName = bundle.getString("download_filename");
}
handler = new Handler();
if (intent.getAction().equalsIgnoreCase(START_DOWNLOAD)) {
Intent notificationIntent = new Intent(mContext, MainActivity.class);
notificationIntent.setAction(MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notificationIntent, 0);
Intent pauseIntent = new Intent(mContext, DownloadService.class);
pauseIntent.setAction(PAUSE_DOWNLOAD);
PendingIntent pausePendingIntent = PendingIntent.getService(mContext, 0, pauseIntent, 0);
Intent stopIntent = new Intent(mContext, DownloadService.class);
stopIntent.setAction(STOP_DOWNLOAD);
PendingIntent stopPendingIntent = PendingIntent.getService(mContext, 0, stopIntent, 0);
mNotiManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
builder = new NotificationCompat.Builder(mContext)
.setContentTitle("Download demo")
.setTicker("downloading...")
.setSmallIcon(R.mipmap.ic_launcher)
.setOngoing(true)
.setContentIntent(pendingIntent)
.addAction(R.drawable.ic_pause_download, "pause", pausePendingIntent)
.addAction(R.drawable.ic_cancel_download, "stop", stopPendingIntent);
notification = builder.build();
startForeground(DOWNLOAD_NOTIFICATION, notification);
new DownloadFileAsync(downloadUrl, downloadFileName).execute();
} else if (intent.getAction().equalsIgnoreCase(PAUSE_DOWNLOAD)) {
Toast.makeText(mContext.getApplicationContext(), "Download Pause !", Toast.LENGTH_LONG).show();
} else if (intent.getAction().equalsIgnoreCase(STOP_DOWNLOAD)) {
Toast.makeText(mContext.getApplicationContext(), "Download Stop !", Toast.LENGTH_LONG).show();
mNotiManager.cancel(DOWNLOAD_NOTIFICATION);
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
和我的异步任务
private class DownloadFileAsync extends AsyncTask<Void, Integer, Void> {
private HttpURLConnection mUrlConnection;
private File downloadFile = null;
private String downloadUrl = "";
private String downloadFileName = "";
public DownloadFileAsync(String downloadUrl, String downloadFileName) {
this.downloadUrl = downloadUrl;
this.downloadFileName = downloadFileName;
}
@Override
protected Void doInBackground(Void... objects) {
try {
URL url = new URL(downloadUrl);
mUrlConnection = (HttpURLConnection) url.openConnection();
mUrlConnection.setRequestMethod("GET");
mUrlConnection.setDoOutput(true);
mUrlConnection.setReadTimeout(20 * 1000);
mUrlConnection.setConnectTimeout(20 * 1000);
mUrlConnection.connect();
int responseCode = mUrlConnection.getResponseCode();
Log.e("Response Code===", responseCode + "");
if (responseCode == HttpURLConnection.HTTP_OK) {
mDownloadMaxSize = Long.parseLong(mUrlConnection.getHeaderField("content-length"));
downloadFile = new File(Environment.getExternalStorageDirectory(), downloadFileName);
if (!downloadFile.exists()) {
downloadFile.createNewFile();
} else {
long length = downloadFile.length();
mUrlConnection.setRequestProperty("Request", "bytes = " + length + "-");
}
InputStream in = new BufferedInputStream(mUrlConnection.getInputStream());
DataInputStream dis = new DataInputStream(in);
FileOutputStream fos = new FileOutputStream(downloadFile, true);
byte buffer[] = new byte[1024];
int length;
while ((length = dis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
mDownloadProgress += length;
publishProgress((int) (mDownloadProgress * 100 / mDownloadMaxSize));
}
in.close();
fos.close();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (mUrlConnection != null) {
mUrlConnection.disconnect();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
builder.setProgress(100, values[0], false);
mNotiManager.notify(DOWNLOAD_NOTIFICATION, builder.build());
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
builder.setProgress(0, 0, false);
mNotiManager.notify(DOWNLOAD_NOTIFICATION, builder.build());
}
}
请帮我解决这个问题。
提前致谢。
你的代码没问题。只需在后台方法中放置一些延迟,看看是否可以看到任何变化。
我创建了一个从前台服务下载文件并在通知进度条中显示下载进度的演示。我在服务中使用 asynctask,在 asynctask 中我使用 HttpUrlConnection 从 Internet 下载文件并更新 onProgressUpdate() 中的进度。我显示以下错误 跳过了 145 帧!应用程序可能在其主线程上做了太多工作。
和phone被绞死。
Service.java
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG + "===", "onStartCommand");
String downloadUrl = "", downloadFileName = "";
Bundle bundle = intent.getExtras();
if (bundle != null) {
downloadUrl = bundle.getString("download_url");
downloadFileName = bundle.getString("download_filename");
}
handler = new Handler();
if (intent.getAction().equalsIgnoreCase(START_DOWNLOAD)) {
Intent notificationIntent = new Intent(mContext, MainActivity.class);
notificationIntent.setAction(MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notificationIntent, 0);
Intent pauseIntent = new Intent(mContext, DownloadService.class);
pauseIntent.setAction(PAUSE_DOWNLOAD);
PendingIntent pausePendingIntent = PendingIntent.getService(mContext, 0, pauseIntent, 0);
Intent stopIntent = new Intent(mContext, DownloadService.class);
stopIntent.setAction(STOP_DOWNLOAD);
PendingIntent stopPendingIntent = PendingIntent.getService(mContext, 0, stopIntent, 0);
mNotiManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
builder = new NotificationCompat.Builder(mContext)
.setContentTitle("Download demo")
.setTicker("downloading...")
.setSmallIcon(R.mipmap.ic_launcher)
.setOngoing(true)
.setContentIntent(pendingIntent)
.addAction(R.drawable.ic_pause_download, "pause", pausePendingIntent)
.addAction(R.drawable.ic_cancel_download, "stop", stopPendingIntent);
notification = builder.build();
startForeground(DOWNLOAD_NOTIFICATION, notification);
new DownloadFileAsync(downloadUrl, downloadFileName).execute();
} else if (intent.getAction().equalsIgnoreCase(PAUSE_DOWNLOAD)) {
Toast.makeText(mContext.getApplicationContext(), "Download Pause !", Toast.LENGTH_LONG).show();
} else if (intent.getAction().equalsIgnoreCase(STOP_DOWNLOAD)) {
Toast.makeText(mContext.getApplicationContext(), "Download Stop !", Toast.LENGTH_LONG).show();
mNotiManager.cancel(DOWNLOAD_NOTIFICATION);
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
和我的异步任务
private class DownloadFileAsync extends AsyncTask<Void, Integer, Void> {
private HttpURLConnection mUrlConnection;
private File downloadFile = null;
private String downloadUrl = "";
private String downloadFileName = "";
public DownloadFileAsync(String downloadUrl, String downloadFileName) {
this.downloadUrl = downloadUrl;
this.downloadFileName = downloadFileName;
}
@Override
protected Void doInBackground(Void... objects) {
try {
URL url = new URL(downloadUrl);
mUrlConnection = (HttpURLConnection) url.openConnection();
mUrlConnection.setRequestMethod("GET");
mUrlConnection.setDoOutput(true);
mUrlConnection.setReadTimeout(20 * 1000);
mUrlConnection.setConnectTimeout(20 * 1000);
mUrlConnection.connect();
int responseCode = mUrlConnection.getResponseCode();
Log.e("Response Code===", responseCode + "");
if (responseCode == HttpURLConnection.HTTP_OK) {
mDownloadMaxSize = Long.parseLong(mUrlConnection.getHeaderField("content-length"));
downloadFile = new File(Environment.getExternalStorageDirectory(), downloadFileName);
if (!downloadFile.exists()) {
downloadFile.createNewFile();
} else {
long length = downloadFile.length();
mUrlConnection.setRequestProperty("Request", "bytes = " + length + "-");
}
InputStream in = new BufferedInputStream(mUrlConnection.getInputStream());
DataInputStream dis = new DataInputStream(in);
FileOutputStream fos = new FileOutputStream(downloadFile, true);
byte buffer[] = new byte[1024];
int length;
while ((length = dis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
mDownloadProgress += length;
publishProgress((int) (mDownloadProgress * 100 / mDownloadMaxSize));
}
in.close();
fos.close();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (mUrlConnection != null) {
mUrlConnection.disconnect();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
builder.setProgress(100, values[0], false);
mNotiManager.notify(DOWNLOAD_NOTIFICATION, builder.build());
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
builder.setProgress(0, 0, false);
mNotiManager.notify(DOWNLOAD_NOTIFICATION, builder.build());
}
}
请帮我解决这个问题。 提前致谢。
你的代码没问题。只需在后台方法中放置一些延迟,看看是否可以看到任何变化。