81

アクティビティがあり、その中にクラスがあります。

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) {

    }
}

私は得る:

エラー/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
4

7 に答える 7

147

エラーは自明です...doInBackground()ループすることを意図していないため、に接続されていないバックグラウンドスレッドで実行されますLooper.

ほとんどの場合、Handler を直接インスタンス化する必要はまったくありません...実装が返すデータは、UI スレッドで実行さdoInBackground()れるものに渡されます。onPostExecute()

   mActivity = ThisActivity.this; 

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

問題のスタックトレースに続いて追加:

AsyncTaskGL レンダリング スレッドから開始しようとしているようですLooper.loop()。AsyncTasks は、実際には UI スレッドからのみ実行されるように設計されています。

最も破壊的でない修正は、おそらく を開始Activity.runOnUiThread()する aRunnableで呼び出すことAsyncTaskです。

于 2011-02-15T21:43:29.123 に答える
32

上記の答えはすべて正しいですが、これは可能な限り最も簡単な例だと思います。

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 スレッドの進行状況バーを更新することです。

それが役に立てば幸い!

于 2012-04-05T16:00:18.947 に答える
23

この方法でバックグラウンドスレッドでハンドラーを作成します

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();
    }
于 2014-12-22T09:36:21.570 に答える
12

Activity.runOnUiThread()私にはうまくいきません。この方法で通常のスレッドを作成することで、この問題を回避しました。

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

この方法で GL 更新から呼び出します。

new PullTasksThread().start();
于 2011-08-01T08:40:02.800 に答える