IT

java.lang.RuntimeException : Looper.prepare ()를 호출하지 않고 내부에 생성 할 수 없습니다.

lottoking 2020. 9. 5. 10:11
반응형

java.lang.RuntimeException : Looper.prepare ()를 호출하지 않고 내부에 생성 할 수 없습니다.


명령을 실행하는 Android 앱이 있습니다. 메시지와 함께 토스트 메시지를 표시하고 싶습니다.

이렇게하면 다음 예외가 발생합니다.

Logcat 추적 :

FATAL EXCEPTION: Timer-0 
 java.lang.RuntimeException: Can't create handler inside thread that has not 
    called Looper.prepare()

 at android.os.Handler.<init>(Handler.java:121)
 at android.widget.Toast$TN.<init>(Toast.java:322)
 at android.widget.Toast.<init>(Toast.java:91)
 at android.widget.Toast.makeText(Toast.java:238) 

간단한에서 사용자 인터페이스로 토스트 메시지를 푸시하기위한 해결 방법이 있습니까?


백그라운드에서 토스트 팝업을 만들려고 있었기 때문에 예외가 발생했습니다.
Toast는 사용자 인터페이스로 푸시하기위한 활동이 필요하지만 기능이 없습니다.
따라서 한 가지 해결 방법은 코드에 부모 Activity 및 Toast에 대한 링크를 제공하는 것입니다.

토스트 메시지를 보내 의도에 다음 코드를 보내십시오.

parent.runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(parent.getBaseContext(), "Hello", Toast.LENGTH_LONG).show();
    }
});

이 전형적인를 생성 한 반복적 인 상위 활동에 대한 링크를 유지합니다. 같은 클래스에서 상위 변수를 사용하십시오.

private static YourActivity parent;

다음과 같이 생성 할 때이를 통해 부모 활동을 전달 변수로 전달합니다.

public YourBackgroundThread(YourActivity parent) {
    this.parent = parent;
}

이제 백그라운드 프로그램이 Toast 메시지를 화면에 푸시 할 수 있습니다.


Android는 기본적으로 기본적으로 UI와 어울립니다. 안드로이드 문서에 따르면-

이 문제를 해결하기 위해 UI 외부에서 Android UI 툴킷에 액세스하지 않는 곳입니다. Android는 다른 프로그램에서 UI를 제공하는 여러 방법을 제공합니다. 다음은 도움이 될 수있는 방법 목록입니다.

Activity.runOnUiThread(Runnable)  
View.post(Runnable)  
View.postDelayed(Runnable, long)

이제이 문제를 해결하기위한 다양한 방법이 있습니다. 코드 샘플로 설명하겠습니다

runOnUiThread

new Thread()
{
    public void run()
    {
        myactivity.this.runOnUiThread(new runnable()
        {
            public void run()
            {
                //Do your UI operations like dialog opening or Toast here
            }
        });
    }
}.start();

자벌레

같은에 대한 메시지 루프를 실행하는 데 사용되는 클래스입니다. 기본적으로 기본적으로 내장 된 메시지 루프가 있습니다. 하나를 만들려면 루프를 사용할 때 준비에서 ()를 호출 한 다음 루프 ()를 호출하여 루프가 중지 될 메시지를 처리합니다.

class LooperThread extends Thread {
    public Handler mHandler;

    public void run() {
        Looper.prepare();

        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                // process incoming messages here
            }
        };

        Looper.loop();
    }

AsyncTask

AsyncTask를 사용하면 사용자 인터페이스에서 비동기 작업을 수행 할 수 있습니다. 작업자 스레드에서 차단 작업을 수행 한 다음 스레드 및 / 또는 처리기를 직접 처리 할 필요없이 UI 스레드에 결과를 게시합니다.

public void onClick(View v) {
    new CustomTask().execute((Void[])null);
}


private class CustomTask extends AsyncTask<Void, Void, Void> {

    protected Void doInBackground(Void... param) {
        //Do some work
        return null;
    }

    protected void onPostExecute(Void param) {
        //Print Toast or open dialog
    }
}

매니저

핸들러를 사용하면 스레드의 MessageQueue와 관련된 Message 및 Runnable 개체를 보내고 처리 할 수 ​​있습니다.

Message msg = new Message();


    new Thread()
    {
        public void run()
        {
            msg.arg1=1;
            handler.sendMessage(msg);
        }
    }.start();



    Handler handler = new Handler(new Handler.Callback() {

        @Override
        public boolean handleMessage(Message msg) {
            if(msg.arg1==1)
            {
                //Print Toast or open dialog        
            }
            return false;
        }
    });

내가 한 일은 다음과 같습니다.

  public void displayError(final String errorText) {
    Runnable doDisplayError = new Runnable() {
        public void run() {
            Toast.makeText(getApplicationContext(), errorText, Toast.LENGTH_LONG).show();
        }
    };
    messageHandler.post(doDisplayError);
}

그러면 두 스레드에서 메서드를 호출 할 수 있습니다.

여기서 messageHandler는 활동에서 ..

Handler messageHandler = new Handler();

에서 http://developer.android.com/guide/components/processes-and-threads.html :

또한 Android UI 도구 키트는 스레드로부터 안전하지 않습니다. 따라서 작업자 스레드에서 UI를 조작해서는 안됩니다 . UI 스레드에서 사용자 인터페이스에 대한 모든 조작을 수행해야합니다. 따라서 Android의 단일 스레드 모델에는 두 가지 규칙이 있습니다.

  1. UI 스레드를 차단하지 마십시오.
  2. UI 스레드 외부에서 Android UI 툴킷에 액세스하지 마십시오.

작업자 스레드에서 유휴 상태를 감지하고 주 스레드에서 토스트를 표시해야합니다.

더 자세한 답변을 원하시면 코드를 게시하십시오.

코드 게시 후 :

strings.xml

<string name="idleness_toast">"You are getting late do it fast"</string>

YourWorkerThread.java

Toast.makeText(getApplicationContext(), getString(R.string.idleness_toast), 
    Toast.LENGTH_LONG).show();

AlertDialog를 사용하지 말고 선택하십시오. AlertDialog와 Toast는 서로 다른 두 가지입니다.


runOnUiThread(new Runnable(){
   public void run() {
     Toast.makeText(getApplicationContext(), "Status = " + message.getBody() , Toast.LENGTH_LONG).show();
   }
 });

이것은 나를 위해 작동합니다


간단히 BeginInvokeOnMainThread ()를 사용할 수 있습니다. 장치 기본 (UI) 스레드에서 작업을 호출합니다.

Device.BeginInvokeOnMainThread(() => { displayToast("text to display"); });

간단하고 완벽하게 작동합니다!

편집 : C # Xamarin을 사용하는 경우 작동합니다.

참고 URL : https://stackoverflow.com/questions/17379002/java-lang-runtimeexception-cant-create-handler-inside-thread-that-has-not-call

반응형