[android] Looper.prepare ()를 호출하지 않은 스레드 내부에 핸들러를 만들 수 없습니다.

나는 활동이 있고 거기에 수업이 있습니다.

text=new Dynamictext(...);
text.setText("txt");

내 DynamicText Java에는 다음 코드가 있습니다.

public void setText(String text) {
    this.text=text;
    new asyncCreateText().execute();
    //this.createText(text);
}

//private Handler handler = new Handler();

private class asyncCreateText extends AsyncTask<Void, Void, Void> 
{
    @Override
    protected Void doInBackground(Void... unused) {
        return null;
    }

    @Override
    protected void onPostExecute(Void unused) {

    }
}

나는 얻다:

ERROR / AndroidRuntime (5176) : 원인 : java.lang.RuntimeException : Looper.prepare ()를 호출하지 않은 스레드 내부에 핸들러를 만들 수 없습니다.

이 오류를 어떻게 처리 할 수 ​​있습니까?

ERROR/AndroidRuntime(5370): java.lang.ExceptionInInitializerError
ERROR/AndroidRuntime(5370):     at com.l.start.DynamicText.setText(DynamicText.java:125)
ERROR/AndroidRuntime(5370):     at com.l.start.OpenGLRenderer.initfonts(OpenGLRenderer.java:168)
ERROR/AndroidRuntime(5370):     at com.l.start.OpenGLRenderer.init(OpenGLRenderer.java:119)
ERROR/AndroidRuntime(5370):     at com.l.start.OpenGLRenderer.onSurfaceChanged(OpenGLRenderer.java:90)
ERROR/AndroidRuntime(5370):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1120)
ERROR/AndroidRuntime(5370):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:975)

ERROR/AndroidRuntime(5370): Caused by: java.lang.RuntimeException:
    Can't create handler inside thread that has not called Looper.prepare()
ERROR/AndroidRuntime(5370):     at android.os.Handler.<init>(Handler.java:121)
ERROR/AndroidRuntime(5370):     at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
ERROR/AndroidRuntime(5370):     at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
ERROR/AndroidRuntime(5370):     at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
ERROR/AndroidRuntime(5370):     ... 6 more



답변

오류는 자명합니다 … doInBackground()루프를 의도하지 않았기 때문에 Looper.

처리기를 직접 인스턴스화하고 싶지는 않을 doInBackground()것입니다. 구현에서 반환 하는 데이터 onPostExecute()는 UI 스레드에서 실행되는 데이터 로 전달됩니다 .

   mActivity = ThisActivity.this;

    mActivity.runOnUiThread(new Runnable() {
     public void run() {
     new asyncCreateText().execute();
     }
   });

질문에 나타나는 스택 추적에 따라 추가 :

AsyncTaskGL 렌더링 스레드에서 시작하려고하는 것 같습니다 . 그렇게하지 마십시오 Looper.loop(). AsyncTasks는 실제로 UI 스레드에서만 실행되도록 설계되었습니다.

최소 파괴적인 수정은 아마 전화를하는 것입니다 Activity.runOnUiThread()로모그래퍼 Runnable여러분의 해제가 차기 AsyncTask.


답변

위의 모든 답변은 정확하지만 이것이 가능한 가장 쉬운 예라고 생각합니다.

public class ExampleActivity extends Activity {
    private Handler handler;
    private ProgressBar progress;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        progress = (ProgressBar) findViewById(R.id.progressBar1);
        handler = new Handler();
    }

    public void clickAButton(View view) {
        // Do something that takes a while
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                handler.post(new Runnable() { // This thread runs in the UI
                    @Override
                    public void run() {
                        progress.setProgress("anything"); // Update the UI
                    }
                });
            }
        };
        new Thread(runnable).start();
    }
}

이것이하는 일은 액티비티에 선언 된 핸들러의 post () 메서드를 통해 전달 된 완전히 다른 스레드에서 UI 스레드의 진행률 표시 줄을 업데이트하는 것입니다.

도움이 되었기를 바랍니다.


답변

이런 식으로 백그라운드 스레드에서 핸들러를 생성합니다.

private void createHandler() {
        Thread thread = new Thread() {
          public void run() {
               Looper.prepare();

               final Handler handler = new Handler();
               handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                       // Do Work
                        handler.removeCallbacks(this);
                        Looper.myLooper().quit();
                   }
                }, 2000);

                Looper.loop();
            }
        };
        thread.start();
    }


답변

Activity.runOnUiThread()나를 위해 작동하지 않습니다. 이 방법으로 일반 스레드를 만들어이 문제를 해결했습니다.

public class PullTasksThread extends Thread {
   public void run () {
      Log.d(Prefs.TAG, "Thread run...");
   }
}

다음과 같이 GL 업데이트에서 호출합니다.

new PullTasksThread().start();


답변

UI 스레드에서 asyntask를 실행 해보십시오. 나는 똑같이하지 않을 때이 문제에 직면했습니다!


답변

이 시도

    Handler mHandler = new Handler(Looper.getMainLooper());
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
 //your code here that talks with the UI level widgets/ try to access the UI 
//elements from this block because this piece of snippet will run in the UI/MainThread.                                     
                            }
                        });


답변