1

我正在使用异步任务上传视频文件。为了跟踪进度,我在状态栏中运行了一个通知。通知正常工作和更新,但会导致严重的性能问题,导致状态栏崩溃并需要重新启动手机。我的代码如下:从AsynTask更新通知栏会导致通知栏崩溃

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上测试这个。我按下通知栏时会出现问题,导致问题扩大。手机会冻结并触摸,然后我是否会实际进入通知栏或通知栏会崩溃。如果我确实进入通知栏,性能问题仍然存在,再次关闭通知栏与打开通知栏一样棘手。 我在想什么可能是发送通知更新的绝对数量可能会导致问题,但我不知道。

欣赏任何想法和建议。

回答

3

你的怀疑是对的。 以下指令

publishProgress((int) ((num/(float) totalSize) * 100)); 

将在很短的时间间隔内被频繁地调用。

我会在这种情况下做的是存储我想要显示的澎湃偶像,并且只有在自最近一次通话以来发生变化时才发送。

doInBackground方法,你可以声明一个变量,例如:

int lastPourcent = 0; 

然后,在transferred方法:

int currentPoucent = (int) ((num/(float) totalSize) * 100); 
if (currentPourcent > lastPourcent) { 
    publishProgress(currentPourcent); 
    lastPourcent = currentPourcent; 
} 

它会调用的次数显著减少对刷新方法通知。

2

问题是,您的代码在每次执行publishProgress()时都会更新Notification服务并进行更新。我所做的以及你应该做的是实现一个不会使服务溢出的解决方案,而是让你的代码每5%或10%更新一次Notification