Android-스레드를 중지하는 가장 좋고 안전한 방법
Android에서 스레드를 중지하는 가장 좋은 방법을 알고 싶습니다. AsyncTask
대신 사용할 수 있고 cancel()
방법 이 있다는 것을 알고 있습니다 . Thread
내 상황에서 s 를 사용해야 합니다. 내가 사용하는 방법은 다음과 같습니다 Thread
.
Runnable runnable = new Runnable() {
@Override
public void run() {
//doing some work
}
};
new Thread(runnable).start();
그렇다면 스레드를 중지하는 가장 좋은 방법이 무엇인지 아는 사람이 있습니까?
스레드 지원 인터럽트를 만들어야합니다. 기본적으로 yourThread.interrupt()
스레드를 중지하기 위해 호출 할 수 있으며 run () 메서드에서 주기적으로 상태를 확인해야합니다.Thread.interrupted()
여기에 좋은 튜토리얼이 있습니다 .
이 상황은 표준 Java와 전혀 다르지 않습니다. 표준 방법을 사용하여 스레드를 중지 할 수 있습니다.
class WorkerThread extends Thread {
volatile boolean running = true;
public void run() {
// Do work...
if (!running) return;
//Continue doing the work
}
}
주요 아이디어는 때때로 필드의 가치를 확인하는 것입니다. 스레드를 중지해야하는 경우 running
false로 설정 합니다. 또한 Chris가 지적했듯이 중단 메커니즘을 사용할 수 있습니다.
그건 그렇고, AsyncTask를 사용할 때 접근 방식은 크게 다르지 않습니다. 유일한 차이점은 isCancel()
특수 필드를 갖는 대신 작업에서 메서드 를 호출해야한다는 것입니다 . 를 호출 cancel(true)
하지만이 메커니즘을 구현하지 않으면 스레드가 여전히 저절로 중지되지 않고 끝까지 실행됩니다.
Android에서는 일반 Java 환경과 동일한 규칙이 적용됩니다. Java에서 스레드는 종료되지 않지만 스레드 중지는 협력적인 방식으로 수행됩니다 . 스레드는 종료하도록 요청되고 스레드는 정상적으로 종료 될 수 있습니다.
종종 volatile boolean
해당 값으로 설정되면 스레드가 주기적으로 확인하고 종료 하는 필드가 사용됩니다.
나는 하지 않을 를 사용하는 boolean
스레드가해야하는지 여부를 확인하기 위해 종료 . volatile
필드 수정 자로 사용하면 안정적으로 작동하지만 코드가 더 복잡해지면 while
루프 내에서 다른 차단 방법을 대신 사용 하기 때문에 코드가 전혀 종료되지 않거나 적어도 시간이 더 오래 걸릴 수 있습니다. 아마도 원한다.
특정 차단 라이브러리 방법은 중단을 지원합니다.
모든 스레드에는 이미 부울 플래그 인터럽트 상태 가 있으므로 이를 사용해야합니다. 다음과 같이 구현할 수 있습니다.
public void run() {
try {
while(!Thread.currentThread().isInterrupted()) {
// ...
}
} catch (InterruptedException consumed)
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
Java Concurrency in Practice 에서 가져온 소스 코드 입니다. cancel()
메서드가 공용 이므로 원하는대로 다른 스레드가이 메서드를 호출하도록 할 수 있습니다.
interrupted
현재 스레드의 중단 된 상태를 지우는 이름 이 잘못된 정적 메서드도 있습니다 .
Thread.stop()
스레드를 중지하는 데 사용 될 수있는 방법은 사용되지 않습니다; 자세한 정보는 다음을 참조하십시오. Thread.stop, Thread.suspend 및 Thread.resume이 더 이상 사용되지 않는 이유는 무엇입니까? .
가장 좋은 방법은 스레드 자체가 참조하는 변수를 가지고 변수가 특정 값과 같으면 자발적으로 종료하는 것입니다. 그런 다음 스레드를 종료하려는 경우 코드 내에서 변수를 조작합니다. 물론 AsyncTask
대신 사용할 수도 있습니다 .
현재 그리고 안타깝게도 스레드를 중지하기 위해 아무것도 할 수 없습니다 ....
Matt의 답변에 무언가를 추가하면 우리가 호출 할 수 interrupt()
있지만 스레드를 중지하지는 않습니다. 시스템이 일부 스레드를 종료하려고 할 때 스레드를 중지하도록 시스템에 지시합니다. 휴식은 시스템에 의해 이루어지며을 호출하여 확인할 수 있습니다 interrupted()
.
[ps : 정말 같이 가신다면 interrupt()
전화를 걸어 잠깐자는 실험을 해보 시죠 interrupt()
]
스레드를 중지하는 데 선호되는 두 가지 방법이 있습니다.
휘발성 부울 변수를 만들고 그 값을 false로 변경하고 스레드 내부를 확인합니다.
휘발성 isRunning = false;
public void run () {if (! isRunning) {return;}}
또는 스레드 내부에서받을 수있는 interrupt () 메서드를 사용할 수 있습니다.
SomeThread.interrupt ();
public void run () {if (Thread.currentThread.isInterrupted ()) {return;}}
문제는 스레드가 실행 중인지 여부를 확인해야한다는 것입니다 !?
들:
private boolean runningThread = false;
스레드에서 :
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep((long) Math.floor(speed));
if (!runningThread) {
return;
}
yourWork();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
스레드를 중지하려면 아래 필드를 만들어야합니다.
private boolean runningThread = false;
이 방법을 사용했습니다.
Looper.myLooper().quit();
당신은 시도 할 수 있습니다.
이것은 나를 위해 이렇게 작동했습니다. 주요 활동에 정적 변수를 도입하고 아래에서 어떻게했는지 정기적으로 확인하십시오.
public class MainActivity extends AppCompatActivity {
//This is the static variable introduced in main activity
public static boolean stopThread =false;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread thread = new Thread(new Thread1());
thread.start();
Button stp_thread= findViewById(R.id.button_stop);
stp_thread.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v){
stopThread = true;
}
}
}
class Thread1 implements Runnable{
public void run() {
// YOU CAN DO IT ON BELOW WAY
while(!MainActivity.stopThread) {
Do Something here
}
//OR YOU CAN CALL RETURN AFTER EVERY LINE LIKE BELOW
process 1 goes here;
//Below method also could be used
if(stopThread==true){
return ;
}
// use this after every line
process 2 goes here;
//Below method also could be used
if(stopThread==true){
return ;
}
// use this after every line
process 3 goes here;
//Below method also could be used
if(stopThread==true){
return ;
}
// use this after every line
process 4 goes here;
}
}
}
프로젝트에 핸들러가있는 스레드 클래스가있는 경우 여기에서 중지하려는 경우 프래그먼트 클래스 중 하나에서 시작했을 때 프래그먼트가 스택에서 제거 될 때 앱을 중지하고 충돌을 방지하는 방법이 있습니다.
이 코드는 Kotlin에 있습니다. 완벽하게 작동합니다.
class NewsFragment : Fragment() {
private var mGetRSSFeedsThread: GetRSSFeedsThread? = null
private val mHandler = object : Handler() {
override fun handleMessage(msg: Message?) {
if (msg?.what == GetRSSFeedsThread.GETRSSFEEDSTHREAD_SUCCESS) {
val updateXMLdata = msg.obj as String
if (!updateXMLdata.isNullOrEmpty())
parseUpdatePager(CommonUtils.getJSONObjectFromXML(updateXMLdata).toString())
} else if (msg?.what == GetRSSFeedsThread.GETRSSFEEDSTHREAD_SUCCESS) {
BaseActivity.make_toast(activity, resources.getString(R.string.pleaseTryAgain))
}
}
}
private var rootview: View? = null;
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
rootview = inflater?.inflate(R.layout.fragment_news, container, false);
news_listView = rootview?.findViewById(R.id.news_listView)
mGetRSSFeedsThread = GetRSSFeedsThread(this.activity, mHandler)
if (CommonUtils.isInternetAvailable(activity)) {
mGetRSSFeedsThread?.start()
}
return rootview
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true);
}
override fun onAttach(context: Context?) {
super.onAttach(context)
println("onAttach")
}
override fun onPause() {
super.onPause()
println("onPause fragment may return to active state again")
Thread.interrupted()
}
override fun onStart() {
super.onStart()
println("onStart")
}
override fun onResume() {
super.onResume()
println("onResume fragment may return to active state again")
}
override fun onDetach() {
super.onDetach()
println("onDetach fragment never return to active state again")
}
override fun onDestroy() {
super.onDestroy()
println("onDestroy fragment never return to active state again")
//check the state of the task
if (mGetRSSFeedsThread != null && mGetRSSFeedsThread?.isAlive!!) {
mGetRSSFeedsThread?.interrupt();
} else {
}
}
override fun onDestroyView() {
super.onDestroyView()
println("onDestroyView fragment may return to active state again")
}
override fun onStop() {
super.onStop()
println("onStop fragment may return to active state again")
}
}
Above code stops the running thread when you switch to any other fragment or activity from current fragment. also it recreates when you return to current fragment
Try Like this
Thread thread = new Thread() {
@Override
public void run() {
Looper.prepare();
while(true){
Log.d("Current Thread", "Running");
try{
Thread.sleep(1000);
}catch(Exeption Ex){ }
}
}
}
thread.start();
thread.interrupt();
Inside of any Activity class you create a method that will assign NULL to thread instance which can be used as an alternative to the depreciated stop() method for stopping thread execution:
public class MyActivity extends Activity {
private Thread mThread;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mThread = new Thread(){
@Override
public void run(){
// Perform thread commands...
for (int i=0; i < 5000; i++)
{
// do something...
}
// Call the stopThread() method.
stopThread(this);
}
};
// Start the thread.
mThread.start();
}
private synchronized void stopThread(Thread theThread)
{
if (theThread != null)
{
theThread = null;
}
}
}
This works for me without a problem.
참고URL : https://stackoverflow.com/questions/8505707/android-best-and-safe-way-to-stop-thread
'Program Tip' 카테고리의 다른 글
Visual Studio에서 표준 인코딩을 설정하는 방법 (0) | 2020.10.17 |
---|---|
numpy 배열에서 다른 배열로 데이터를 복사하는 방법 (0) | 2020.10.16 |
조각 셰이더는 픽셀 색상에 사용할 변수를 어떻게 알 수 있습니까? (0) | 2020.10.16 |
Meteor로 파일 업로드를 어떻게 처리할까요? (0) | 2020.10.16 |
자바 스크립트 만 사용하여 div 태그의 텍스트를 얻는 방법 (jQuery 없음) (0) | 2020.10.16 |