簡體   English   中英

為什么在Android中即使調用stopService后服務中的線程也不會停止?

[英]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 ,因為您的threadservice在單獨的進程中運行。 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;
    }
}

現在在您的onDestroyonStop您可以調用myThread.setStop()並等待,直到if (isStop) return; 被稱為->您的線程實際上將停止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM