我正在使用异步任务上传视频文件。为了跟踪进度,我在状态栏中运行了通知。通知正常工作和更新,但它会导致严重的性能问题,导致状态栏崩溃并且需要重新启动手机。我的代码如下:
private class UploadMedia extends AsyncTask<Void, Integer, String> {
private int NOTIFICATION_ID = 1;
private CharSequence _contentTitle;
private final NotificationManager _notificationManager = (NotificationManager) getActivity()
.getApplicationContext()
.getSystemService(
getActivity().getApplicationContext().NOTIFICATION_SERVICE);
Notification _notification;
PendingIntent _pendingIntent;
private long totalSize;
private int _progress = 0;
private InputStreamBody isb;
private File uploadFile;
protected void onPreExecute() {
Intent intent = new Intent();
_pendingIntent = PendingIntent.getActivity(getActivity(), 0,
intent, 0);
_contentTitle = "Uploader " + mediaTitle + " til Skoletube";
CharSequence contentText = _progress + "% complete";
_notification = new Notification(R.drawable.icon, _contentTitle,
System.currentTimeMillis());
_notification.flags = _notification.flags
| Notification.FLAG_ONGOING_EVENT;
_notification.contentIntent = _pendingIntent;
_notification.setLatestEventInfo(getActivity(), _contentTitle,
contentText, _pendingIntent);
_notificationManager.notify(NOTIFICATION_ID, _notification);
Toast.makeText(getActivity(), "Starter upload", Toast.LENGTH_SHORT)
.show();
try {
uploadFile = new File(_mediaFile.getPath());
// FileInputStream is = new FileInputStream(uploadFile);
//
// ByteArrayOutputStream bos = new ByteArrayOutputStream();
// byte[] b = new byte[1024];
// int bytesRead;
// while ((bytesRead = is.read(b)) != -1) {
// bos.write(b, 0, bytesRead);
// }
// byte[] data = bos.toByteArray();
//
// isb = new InputStreamBody(new ByteArrayInputStream(data),
// uploadFile.getName());
} catch (Exception ex) {
Log.i(TAG,
"Pre execute - oh noes... D: "
+ ex.getLocalizedMessage());
}
}
@Override
protected String doInBackground(Void... params) {
String result = "";
try {
// Inititate connectionparts
HttpClient client = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(
"http://www.skoletube.dk/beta/api_userupload.php");
CustomMultipartEntity multipartE = new CustomMultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE,
new ProgressListener() {
@Override
public void transferred(long num) {
publishProgress((int) ((num / (float) totalSize) * 100));
}
});
// Add the post elements
String timestamp = String
.valueOf(System.currentTimeMillis() / 1000);
String mode = "xml";
String hashSum = Utils.md5(ActiveUser.getPartner() + timestamp
+ ActiveUser.getInstance().getToken()
+ ActiveUser.getInstance().getSecret()
+ ActiveUser.getInstance().getUserID()
+ spnChannel.getSelectedItem().toString()
+ mediaDescribtion + "KEYWORDLOL"
+ spnPublic.getSelectedItem().toString() + mediaTitle
+ ActiveUser.getSharedkey());
multipartE.addPart("uid", new StringBody(ActiveUser
.getInstance().getUserID()));
multipartE.addPart("token", new StringBody(ActiveUser
.getInstance().getToken()));
multipartE.addPart("token_secret", new StringBody(ActiveUser
.getInstance().getSecret()));
multipartE.addPart("partner",
new StringBody(ActiveUser.getPartner()));
multipartE.addPart("timestamp",
new StringBody(timestamp.toString()));
multipartE.addPart("key", new StringBody(hashSum));
multipartE.addPart("video_title", new StringBody(mediaTitle));
multipartE.addPart("video_desc", new StringBody(
mediaDescribtion));
multipartE.addPart("video_keyword",
new StringBody("KEYWORDLOL"));
multipartE.addPart("video_privacy", new StringBody(spnPublic
.getSelectedItem().toString()));
multipartE.addPart("video_channel", new StringBody(spnChannel
.getSelectedItem().toString()));
multipartE.addPart("videoupload", new FileBody(uploadFile));
postRequest.setEntity(multipartE);
totalSize = multipartE.getContentLength();
HttpResponse loginResponse = client.execute(postRequest);
HttpEntity theEnt = loginResponse.getEntity();
result = EntityUtils.toString(theEnt);
Log.i(TAG, "Result: " + result);
} catch (Exception ex) {
Log.i(TAG,
"Do in background - oh noes... D: "
+ ex.getLocalizedMessage());
}
return result;
}
@Override
protected void onProgressUpdate(Integer... progress) {
if (_notification == null)
return;
_progress = progress[0];
_contentTitle = "Uploader " + mediaTitle + " til Skoletube";
CharSequence contentText = _progress + "% complete";
_notification.setLatestEventInfo(getActivity(), _contentTitle,
contentText, _pendingIntent);
_notificationManager.notify(NOTIFICATION_ID, _notification);
}
@Override
protected void onPostExecute(String result) {
_notificationManager.cancel(NOTIFICATION_ID);
}
}
我在HTC Sensation上测试这个。问题发生在我按下通知栏的瞬间,导致它扩展。手机会冻结并触摸它,无论我是否真的到达通知栏或通知栏都会崩溃。如果我确实进入通知栏,性能问题仍然存在,再次关闭通知栏就像打开它一样棘手。 我所想的可能是发送的通知更新数量可能导致问题,但我不确定。
欣赏任何想法和建议。
答案 0 :(得分:3)
你的怀疑是正确的。 以下说明
publishProgress((int) ((num / (float) totalSize) * 100));
会在很短的时间间隔内被频繁调用。
在这种情况下,我会做的是存储我想要显示的pourcent avancement,并且只有在最近一次调用后它发生了变化才会发送。
在doInBackground
方法中,您可以声明一个变量,例如:
int lastPourcent = 0;
然后,在transferred
方法中:
int currentPoucent = (int) ((num / (float) totalSize) * 100);
if (currentPourcent > lastPourcent) {
publishProgress(currentPourcent);
lastPourcent = currentPourcent;
}
它将显着减少对通知的刷新方法的调用次数。
答案 1 :(得分:2)
问题是,每次执行Notification
时,您的代码都会溢出publishProgress()
服务,并带有更新。我所做的以及你应该做的是实现一个不会溢出服务的解决方案,而是让你的代码每隔5%或10%更新Notification
。