2015-11-12 37 views
0

我有良好的啓動和使用基本服務的概念。我的意思是不要複雜。在我的應用程序中,我想要一個不應該在任何情況下被終止的服務,並且應該從服務器下載一些文件,然後它應該調用stopSelf。我通過以下方式提供服務。但在分享它的整個代碼之前,讓我告訴你我在做什麼當用戶關閉最近的應用程序的應用程序時,粘滯服務正在死亡

  1. 服務中,我傳遞了一系列url(字符串數組),它必須從服務器下載所有文件。
  2. 我正在使用異步任務從服務器下載。
  3. 在這個整個過程中,我得到了xml中的第一個響應,然後我解析它,並獲取JSON字符串(抱歉,我的web服務設計器像我一樣麻木)。因此經過這兩次轉換後,我將數據存儲在數據庫中,然後開始下載文件並將其保存到設備並將其路徑存儲在數據庫中。 (這一切工作正常)
  4. 我正在計算和更新通知欄中的進度。 (顯示用戶多大的文件已經下載)我真正想要的

    我想,當用戶從最近的應用程序列表中刪除我的服務應該不會被殺死,

,這樣它應該繼續下載並繼續更新通知欄中的狀態。我正在使用通知管理器來更新進度。

究竟發生什麼事

當我關閉應用程序從最近的應用程序托盤,我覺得我的服務就會被殺死和下載過程停止,也停止更新在通知欄,其中的通知進度正如我希望它繼續運行直到下載過程完成。

這裏是我的代碼的一些方法確實不值得 這裏要討論的如解析XML或JSON

這被簡化爲代碼

public class MyDemoService extends Service { 
private static final String TAG = "MyDemoService"; 
private static final int NOTIFICATION_ID = 1; 
private LocalBinder m_binder = new LocalBinder(); 
private NotificationManager mNotifyManager; 
private NotificationCompat.Builder mBuilder; 
myAsyncTask myWebFetch; 
// Timer to update the ongoing notification 
private final long mFrequency = 100; // milliseconds 
private final int TICK_WHAT = 2; 

public class LocalBinder extends Binder { 
    MyDemoService getService() { 
     return MyDemoService.this; 
    } 
} 

private Handler mHandler = new Handler() { 
    public void handleMessage(Message m) { 
     updateNotification(); 
     sendMessageDelayed(Message.obtain(this, TICK_WHAT), mFrequency); 
    } 
}; 

@Override 
public IBinder onBind(Intent intent) { 
    Log.d(TAG, "bound"); 

    return m_binder; 
} 

@Override 
public void onCreate() { 
    super.onCreate(); 
    Log.d(TAG, "created"); 
    mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 

} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    return Service.START_STICKY; 
} 

@Override 
public void onTaskRemoved(Intent rootIntent) { 
    super.onTaskRemoved(rootIntent); 
    Log.d(TAG, "Removed"); 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    Log.d(TAG, "Destroyed"); 
} 


public void updateNotification() { 
    // Log.d(TAG, "updating notification"); 

    Intent notificationIntent = new Intent(this, MainActivity.class); 
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 

} 


public void hideNotification() { 
    Log.d(TAG, "removing notification"); 
    mNotifyManager.cancel(NOTIFICATION_ID); 
    mHandler.removeMessages(TICK_WHAT); 
} 

public void start() { 
    Log.d(TAG, "start"); 
    mBuilder = 
      new NotificationCompat.Builder(MyDemoService.this) 
        .setSmallIcon(R.drawable.download) 
        .setContentTitle("SMU") 
        .setContentText("Downloading Images"); 
    Intent targetIntent = new Intent(MyDemoService.this, MainActivity.class); 
    PendingIntent contentIntent = PendingIntent.getActivity(MyDemoService.this, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT); 
    mBuilder.setContentIntent(contentIntent); 
    mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build()); 
    myWebFetch = new myAsyncTask(); 
    myWebFetch.execute(); 
} 

class myAsyncTask extends AsyncTask<String, Integer, Void> { 
    MyDB myDB; 


    myAsyncTask() { 
     myDB = new MyDB(MyDemoService.this); 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 
     mBuilder.setContentText("Download complete"); 
     // Removes the progress bar 
     mBuilder.setProgress(0, 0, false); 
     mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build()); 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
     super.onProgressUpdate(values); 
     mBuilder.setProgress(100, values[0], false); 
     mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build()); 
    } 

    @Override 
    protected Void doInBackground(String... params) { 
     //set the download URL, a url that points to a file on the internet 
     getJSON("http://*****", 1000000); 
     return null; 
    } 


    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     mBuilder.setProgress(100, 0, false); 
     mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build()); 
    } 

    public void getJSON(String url, int timeout) { 
     HttpURLConnection c = null; 
     try { 
      URL u = new URL(url); 
      c = (HttpURLConnection) u.openConnection(); 
      c.setRequestMethod("GET"); 
      c.setUseCaches(false); 
      c.setAllowUserInteraction(false); 
      c.setConnectTimeout(timeout); 
      c.setReadTimeout(timeout); 
      c.setInstanceFollowRedirects(false); 
      c.connect(); 
      int status = c.getResponseCode(); 

      if (status == 200) { 
       String readStream = readStream(c.getInputStream()); 
       if (readStream != null) { 
        JsonParser mJsonParser = new JsonParser(MyDemoService.this); 
        mJsonParser.parseJaSon(readStream); 
        ArrayList<SuitDetails> mImageList = new ArrayList<>(myDB.GetAllData()); 

        if (mImageList != null) { 
         //NOW HERE DOWNLOADING IMAGES FROM URL WE GOT SAVED IN DB AFTER PARSING 
         downloadImages(mImageList); 

        } 
       } 

      } 

     } catch (MalformedURLException ex) { 
      Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); 
     } catch (IOException ex) { 
      Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); 
     } finally { 
      if (c != null) { 
       try { 
        c.disconnect(); 
       } catch (Exception ex) { 
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
     } 

    } 

    @TargetApi(Build.VERSION_CODES.KITKAT) 
    private String readStream(InputStream in) { 
     //parsing my input stream and sending back string 
     return jsonString.toString(); 
    } 

    void downloadImages(ArrayList<SuitDetails> arrayList) { 

     try { 

      ArrayList<SuitDetails> imageUrl = arrayList; 
      URL url; 
      float progressImages = 0; 
      HttpURLConnection urlConnection = null; 
      for (int i = 0; i < imageUrl.size(); i++) { 
       progressImages += 100/imageUrl.size(); 
       publishProgress((int) progressImages); 
       url = new URL(imageUrl.get(i).getPath().toString()); 
       //create the new connection 
       urlConnection = (HttpURLConnection) url.openConnection(); 
       //set up some things on the connection 
       urlConnection.setRequestMethod("GET"); 
       urlConnection.setDoOutput(false); 
       urlConnection.setUseCaches(false); 
       urlConnection.setAllowUserInteraction(false); 
       urlConnection.setConnectTimeout(60000); 
       urlConnection.setReadTimeout(60000); 
       urlConnection.setInstanceFollowRedirects(false); 
       //and connect! 
       urlConnection.connect(); 
       File storagePath = new File(MyDemoService.this.getExternalFilesDir("TEST") + "/Mytest"); 
       storagePath.mkdirs(); 
       String finalName = imageUrl.get(i).getImageName(); 
       File myImage = new File(storagePath, finalName + ".png"); 
       FileOutputStream fileOutput = new FileOutputStream(myImage); 
       InputStream inputStream = urlConnection.getInputStream(); 
       int totalSize = urlConnection.getContentLength(); 
       int downloadedSize = 0; 
       byte[] buffer = new byte[1024]; 
       int bufferLength = 0; 
       while ((bufferLength = inputStream.read(buffer)) > 0) { 
        //add the data in the buffer to the file in the file output stream (the file on the sd card 
        fileOutput.write(buffer, 0, bufferLength); 
        //add up the size so we know how much is downloaded 
        downloadedSize += bufferLength; 
        //this is where you would do something to report the prgress, like this maybe 
       } 
       //close the output stream when done 
       ContentValues contentValues = new ContentValues(); 
       contentValues.put("Status", "1"); 
       contentValues.put("Path", myImage.getPath().toString()); 
       myDB.UpdateDownloadStatus(contentValues, imageUrl.get(i).getSImageID()); 
       fileOutput.close(); 
      } 
      myDB.closeDb(); 
      //catch some possible errors... 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

}

我知道是長度代碼,但如果你想深入分析它,共享。

,我會提供我如何使用和調用MainActivity這項服務,如果你需要它

回答

1
  1. 你爲什麼不,如果你想要做的東西,網絡使用IntentService
  2. 你應該考慮從documentation

    集意圖重新投遞的喜好在你的構造

加入setIntentRedelivery(true);。通常使用您的首選語義從 構造函數中調用。

如果啓用爲真,onStartCommand(意向,INT,INT)將返回 START_REDELIVER_INTENT,所以如果這個過程之前 onHandleIntent(意向)返回死亡,過程中會重新啓動, 意圖重新發送。如果發送了多個意向,則只保證最近的一個最近的一個被重新遞送。

如果啓用爲false(默認值),onStartCommand(意向,INT,INT) 將返回START_NOT_STICKY,如果過程中死亡,死亡意向與 它一起。

+0

如何,它到底 如果啓用了說,這會治癒的服務將被殺死時,應用程序被終止爲假(默認),onStartCommand(意向,INT,INT)將返回START_NOT_STICKY,如果該進程死亡,意圖隨之死亡。 –

+0

這就是爲什麼我建議將它設置爲true,因此,殺死它會重新傳遞意圖 – thepoosh

+0

我正在發送URL的意圖,當我殺了應用程序它看起來像它recouivers,我有一個檢查,如果URL是空的,它應該停止服務,因此它停止活動,看起來像意圖得到空或空 –

相關問題