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