Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 8 của 8
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Làm sao để stop thread trong android ?

    đoạn code bên dưới là để test việc stop thread trong android
    android có 2 phương thức để stop thread là stop() và interrupt()
    nhưng mình áp dụng cả 2 cách này đều không được.

    Mình mô tả ví bên dưới, khi MainActivity được gọi, nó sẽ tạo đói tượng thread và chạy thread này thread này có dòng lệnh là in ra logcat dòng "thread dang chay" cứ sau 0,5 giây, khi đó nếu mình bấm nút back trên thiết bị thì ứng dụng sẽ gọi phương thức onPause(), onStop() và onDestroy() và ứng dụng được đóng, nhưng nhìn trên logcat vẫn thấy dòng "thread dang chay" được in ra đều đặn. nếu chạy lại chương trình test này từ icon ta sẽ thấy "thread dang chay" in ra với tốc độ gấp đôi, suy ra là có 2 thread đang chạy, nếu chương trình test được mở đi mở lại nhiều lần thì sẽ sinh ra thread tương ứng

    Giờ thì làm sao để stop thread khi chương trình ko được focus nhỉ các bạn ? nếu ko lâu dài nó ngốn tài nguyên máy vì tạo ra vô số thread, và nếu dùng một cái cờ báo cho while trong run() của thread thì thread vẫn tồn tại, chỉ là cái while ko thỏa thôi đúng ko ?


    Mã:
    package com.example.testcycle; import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.widget.Toast; public class MainActivity extends Activity {        Thread thread;    boolean myFlag = true;        @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        tToast("onCreate");        System.out.println("onCreate");                thread = new mythread();        thread.start();    }     public void onStart() {        super.onStart();        tToast("onStart");        System.out.println("onStart");    }     public void onRestart() {        super.onRestart();        tToast("onRestart");        System.out.println("onRestart");    }     public void onResume() {        super.onResume();        tToast("onResume");        System.out.println("onResume");    }     public void onPause() {        super.onPause();        tToast("onPause: bye bye!");        System.out.println("onPause: bye bye!");    }     public void onStop() {        super.onStop();        myFlag = false;        tToast("onStop.");        thread.stop();        System.out.println("onStop");    }     public void onDestroy() {        super.onStop();        tToast("onDestroy.");        System.out.println("onDestroy");        //thread.stop();        thread.interrupt();    }        class mythread extends Thread {        @Override        public void run() {            //while (myFlag) {                  while (true) {                System.out.println("thread dang chay");                try {                    Thread.sleep(500);                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    //e.printStackTrace();                }            }        }    }     private void tToast(String s) {        Context context = getApplicationContext();        int duration = Toast.LENGTH_SHORT;        Toast toast = Toast.makeText(context, s, duration);        toast.show();    }}

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Thread.stop đã deprecated, sử dụng Thread.interrupt method để thay thế là hợp lý rồi. Nhưng có lẽ là cái mythread không hỗ trợ cancel thread thì làm sao mà cancel được? Để lúc nào rảnh một chút Kevin sẽ chạy thử xem sao, nhưng nếu bạn chỉ chạy thread đơn giản vậy thì sử dụng Runable có lẽ sẽ đơn giản hơn!

    Bạn có thể sử dụng thêm join để chờ thread kết thúc hoàn toàn!

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    thay vì while (true) thì while (flag)
    lúc nào muốn stop thread thì flag=false thôi
    xử lí kết thúc thread có thể đặt sau vòng while
    đây là cách dừng thread 1 cách an toàn, toàn vẹn dữ liệu

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trong android không nên dùng lớp Thread sẵn có của java mà nên dùng Handle của android, các phương thức định thời theo chu kỳ, theo độ trễ... có sẵn trong handle, không cần tự viết lại.

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    android có 2 phương thức để stop thread là stop() và interrupt()
    Thread là của core Java, Android là framework thôi.
    - Nếu bạn chưa hiểu Thread kĩ càng, thì không nên dùng. Nhìn vào code, bạn có vẻ như rất lơ tơ mơ về thread, ví dụ thằng myFlag là share variable nó phải là volatile.
    - Activity run trên UI thread, nó tương tự như thằng Swing run trên Event Thread vậy.
    - Nếu bạn có nhiều small tasks ví dụ request/response từ HTTP server chẳng hạn thì dùng ThreadPoolExecutor (trong java.util.concurrent package), thằng này là Thread pools, chứa N threads (fix), rồi dùng queue thread để spawn từng thread vào. Nhưng bạn phải xem xét cân đo sao cho N là hợp lý, quá nhiều Thread thì good throughput nhưng bad performance...
    - Tuy nhiên trong Android, nó có một class AsyncTask cũng dùng Thread pools techniques dùng để xử lý heavy work ở background và post lên UI thread rất tiện. Bạn nên dùng nó hơn là roll your own version.

    Quay lại bài của bạn, trong Java bạn không thể "dừng" hay "kết thúc" hoàn toàn một Thread được. Vì sao, vì trong lúc Thread của bạn đang chạy, nhiều khi dữ liệu vẫn chưa ở trạng thái hoàn chỉnh (inconsistent state), và đây là lý do mà thằng Thread.stop() và Thread.suspend() của Java bị deprecated. Thằng interrrupt() cũng không khá hơn, tên là interrupt tuy nhiên mục đích chính của hàm này chỉ là send một signal interrupt báo với Thread rằng, nó cần stop mà thôi, chứ nó không thật sự stop ngay được.
    Muốn dừng Thread bạn phải có "quy chế" dừng, ví dụ dùng biến "flag" như trên. Ví dụ:

    Đoạn này

    Mã:
    package org.example.threading; import android.os.Bundle;import android.app.Activity;import android.util.Log;import android.view.Menu;import android.widget.Toast; public class MainActivity extends Activity {    private volatile boolean canceled = false;    private Thread internalThread;     @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Toast.makeText(this, "onCreate()", Toast.LENGTH_SHORT).show();        setContentView(R.layout.activity_main);        Runnable r = new Runnable() {            @Override            public void run() {                while (!canceled) {                    Log.v("My Thread", " is running");                    // pretend there is some work                    try {                        Thread.sleep(500);                    } catch (InterruptedException e) {                                            }                }            }        };        internalThread = new Thread(r);        internalThread.start();    }        public void onStart() {        super.onStart();        Toast.makeText(this, "onStart()", Toast.LENGTH_SHORT).show();    }     public void onRestart() {        super.onRestart();        Toast.makeText(this, "onReStart()", Toast.LENGTH_SHORT).show();    }     public void onResume() {        super.onResume();        Toast.makeText(this, "onResume()", Toast.LENGTH_SHORT).show();    }     public void onPause() {        super.onPause();        Toast.makeText(this, "onPause()", Toast.LENGTH_SHORT).show();    }     public void onStop() {        super.onStop();        Toast.makeText(this, "onStop()", Toast.LENGTH_SHORT).show();        synchronized (this) {            canceled = true;        }    }     public void onDestroy() {        super.onStop();        Toast.makeText(this, "onDestroy()", Toast.LENGTH_SHORT).show();    }     @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.activity_main, menu);        return true;    }}

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Khuyên bạn tận dụng AsyncTask và Loaders nhé! Code trên Java thuần và Android không phải lúc nào cũng bê nguyên java sang được.

  7. #7
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi rox_rook
    Mã:
    package org.example.threading; import android.os.Bundle;import android.app.Activity;import android.util.Log;import android.view.Menu;import android.widget.Toast; public class MainActivity extends Activity {    private volatile boolean canceled = false;    private Thread internalThread;     @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Toast.makeText(this, "onCreate()", Toast.LENGTH_SHORT).show();        setContentView(R.layout.activity_main);        Runnable r = new Runnable() {            @Override            public void run() {                while (!canceled) {                    Log.v("My Thread", " is running");                    // pretend there is some work                    try {                        Thread.sleep(500);                    } catch (InterruptedException e) {                                            }                }            }        };        internalThread = new Thread(r);        internalThread.start();    }    }
    code này chưa ổn lắm đâu anh rook_rook [IMG]images/smilies/biggrin.png[/IMG]
    nếu bên trong Thread,Runable mà có tương tác với các user interface thì ứng dụng chạy sẽ bị force close ngay. thường thì để đồng bộ người ta sẽ dùng AsyncTask , Handler thay thế cho Thread

  8. #8
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    @star: Cũng vậy thôi em vì bản chất thằng AsyncTask nó vẫn spawn một thread thôi. Nếu cần update lên UI (Main Thread) thì anh cứ gọi runOnUiThread() thôi. Nhưng thật sự trong Android thì nên dùng AsyncTask và Handler, anh thì quen thằng Swing nên lâu lâu ngứa tay vẫn roll my own thread and get deadlock somewhere [IMG]images/smilies/wink.png[/IMG]!

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •