我有很好的启动和使用基本服务的概念。我的意思是不要复杂。在我的应用程序中,我想要一个不应该在任何情况下被杀死的服务,并且应该从服务器下载一些文件,然后它应该调用stopSelf。我以下列方式提供服务。但在分享整个代码之前,让我告诉你我在做什么
我真正想要的是什么
我希望当用户将其从最近的应用列表中删除时,我的服务不会被杀死,因此它应该继续下载并继续更新通知栏中的状态。我正在使用通知管理器来更新进度。
真实情况
当我从最近的应用程序托盘关闭我的应用程序时,我认为我的服务被杀死并且下载过程停止,并且它还停止更新通知栏中的通知进度,其中我希望它继续运行直到下载过程结束了。
这是我的代码,它被简化,因为有些方法真的不值得 这里讨论如解析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中使用和调用此服务的方式
答案 0 :(得分:1)
IntentService
?setIntentRedelivery(true);
设置意向转发首选项。通常叫做 具有您首选语义的构造函数。
如果enabled为true,则返回onStartCommand(Intent,int,int) START_REDELIVER_INTENT,所以如果此过程在此之前消失 onHandleIntent(Intent)返回,进程将重启并且 意图重新传递。如果已发送多个Intent,则仅发送最多 最近的一个保证被重新传递。
如果enabled为false(默认值),onStartCommand(Intent,int,int) 将返回START_NOT_STICKY,如果进程终止,则Intent将死亡 随之而来。