[英]Why is the thread in a service not stopping even after stopService is called, in Android?
我正在使用服務將圖像上傳到服務器上,這里有一個取消按鈕可以取消上傳,但是問題是當我單擊取消按鈕時,我調用了stopService()
,然后執行了onDestroy
方法。 但是上傳仍然繼續..我想知道這是怎么發生的? 我是一個初學者,我知道在stopService
調用后該服務將被銷毀,這是怎么回事? 誰能幫我?
MyService.java
public class MyService extends Service {
int id=1;
private ProgressDialog pd;
Bitmap image=null;
private static final int MY_NOTIFICATION_ID=1;
NotificationManager notificationManager;
private NotificationManager mNotifyManager;
Notification myNotification;
private android.support.v7.app.NotificationCompat.Builder mBuilder;
RemoteViews contentView;
Thread t;
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
String path;
int i=0;
path = intent.getExtras().getString("key");
Toast.makeText(this, "Service Started"+path, Toast.LENGTH_LONG).show();
Log.e("Service started=" + path, "service");
image= decodeFile(path);
startNotification();
/* pd = new ProgressDialog(MyService.this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Uploading Picture...");
pd.setCanceledOnTouchOutside(true);
pd.setCancelable(true);
pd.show();
pd.setProgress(0);*/
uploadPhoto(image);
// boolean status= isMyServiceRunning();
/* if(!status)//if false
{
myNotification = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle("Cookbook Upload")
.setContentText("Upload Completed")
.setTicker("Cookbook Upload")
.setWhen(System.currentTimeMillis())
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher)
.build();
notificationManager.notify(MY_NOTIFICATION_ID, myNotification);
}*/
return START_STICKY;
}
private void startNotification() {
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
int icon = R.drawable.ic_launcher;
CharSequence notiText = "Your notification from the service";
long meow = System.currentTimeMillis();
Notification notification = new Notification(icon, notiText, meow);
Context context = getApplicationContext();
CharSequence contentTitle = "Cookbook Upload";
CharSequence contentText = "Upload in Progress";
//PENDING INTENT
Intent notificationIntent = new Intent(this, ImageViewActivity.class);
notificationIntent.putExtra("FROM_NOTIFICATION", true);
// notificationIntent.putExtra("first_state", 2);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
int SERVER_DATA_RECEIVED = 1;
notificationManager.notify(SERVER_DATA_RECEIVED, notification);
}
private void EndNotification() {
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
int icon = R.drawable.ic_launcher;
CharSequence notiText = "Your notification from the service";
long meow = System.currentTimeMillis();
Notification notification = new Notification(icon, notiText, meow);
Context context = getApplicationContext();
CharSequence contentTitle = "Cookbook Upload";
CharSequence contentText = "Upload Completed";
//PENDING INTENT
Intent notificationIntent = new Intent(this, ImageViewActivity.class);
notificationIntent.putExtra("Complete_message", 1);
// notificationIntent.putExtra("first_state", 2);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
int SERVER_DATA_RECEIVED = 1;
notificationManager.notify(SERVER_DATA_RECEIVED, notification);
}
private void uploadPhoto(Bitmap bitmap) {
//in this method you upload the photo to the server: omitted for brevity
final Bitmap bit=bitmap;
//
/* int[] progress = new int[0];
pd.setProgress((int) (progress[0]));*/
//
t = new Thread("MyService") {
@Override
public void run() {
try {
Log.e("Service started", "service");
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(Config.FILE_UPLOAD_URL);
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bit.compress(Bitmap.CompressFormat.JPEG, 100, bos);
byte[] data = bos.toByteArray();
entity.addPart("uploaded_file", new ByteArrayBody(data,
"myImage.jpg"));
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost,
localContext);
BufferedReader reader = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
String aux = "";
while ((aux = reader.readLine()) != null) {
builder.append(aux);
}
String sResponse = builder.toString();
} catch (Exception e) {
Log.e(e.getClass().getName(), e.getMessage(), e);
}
stopSelf();
}
};
t.start();
}
public Bitmap decodeFile(String filePath) {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
final int REQUIRED_SIZE = 1024;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
o.inJustDecodeBounds = false;
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
image= BitmapFactory.decodeFile(filePath, o2);
return image;
}
@Override
public void onDestroy() {
super.onDestroy();
t.interrupt();
EndNotification();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
在這里我停止服務
使用此代碼段
t = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
if(flag){//here add a flag
return;
}
t.sleep(5000);
// Toast.makeText(getApplicationContext(), "Horas",
// Toast.LENGTH_LONG).show();
handler.sendEmptyMessage(0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
t.start();
public void onDestroy() {
Toast.makeText(this, "MyService Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
//t.interrupt();
handler.removeCallbacks(t);
super.onDestroy();
flag = false;//here set flag to false
}
是的,您無法通過調用stopService
停止Thread
,因為您的thread
和service
在單獨的進程中運行。 stopService
只能停止您的Service
。 一旦線程運行,您只能將其停止在線程內部,而無法立即停止線程。 安全和最簡單的方法是在線程中聲明一個布爾值標志,然后等待直到檢查了該標志,例如:
public class MyThread extends Thread {
public boolean isStop = false;
public void setStop() {
isStop = true;
}
@Override
public void run() {
super.run();
//Do your work here
if (isStop) return; // check multiple times after doing some hard word
//do somework
if (isStop) return;
}
}
現在在您的onDestroy
或onStop
您可以調用myThread.setStop()
並等待,直到if (isStop) return;
被稱為->您的線程實際上將停止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.