0

マルチスレッドを作成しようとしていますが、いくつかのスマートフォン (SGS2) でこのスタックトレースを取得しています:

java.lang.ExceptionInInitializerError
at com.android.bordeaux.code.model.AnnouncersContainer.setLoudArrayFromJSON_online(AnnouncersContainer.java:68)
at com.android.bordeaux.code.SplashscreenActivity_Second$1.run(SplashscreenActivity_Second.java:55)
Caused by: 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.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
... 2 more 

これが私の主なアクティビティ(スプラッシュスクリーン)で、私のasynctaskの終了を待つために数秒間待機しています:

    public class SplashscreenActivity_Second extends Activity 
        {       
            @Override
            public void onCreate(Bundle savedInstanceState) 
            {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.splashscreen_second);

                // thread
                Thread splashThread = new Thread()
                {
                    @Override
                    public void run()
                    {
                        try
                        {
                            int waited = 0;

                            if (isInternetOn())
                            {
// Here I'm making my asynctask !!
AnnouncersContainer.setLoudArrayFromJSON_online(getApplicationContext());
                                while (waited < 5000)
                                {
                                    sleep(50);
                                    waited += 40;
                                }
                            }
                            else
                            {                       
                                AnnouncersContainer.setLoudArrayFromXML_local(getApplicationContext());
                                while(waited < 5000)
                                {
                                    sleep(50);
                                    waited += 60;
                                }
                            }
                        }
                        catch( InterruptedException e )
                        {
                            e.printStackTrace();
                        }
                        finally
                        {
                            Intent intent_to_tabhost = new Intent(SplashscreenActivity_Second.this, MyTabActivity.class);
                            startActivity(intent_to_tabhost);
                            finish();
                        }
                    }
                };
                splashThread.start();
            }
}

これが私の asynctask です:

public class DownloadAnnouncers extends AsyncTask<Void, Integer, Boolean>
{
    public static Boolean loadFinished = false;

    //JSON variables..


    private static String url = null;

    Context context;

    public DownloadAnnouncers(Context context) 
    {
        this.context = context;
    }

    @Override
    protected void onPreExecute() 
    {
        super.onPreExecute();
    }

    protected Boolean doInBackground(Void... params) 
    {

    // fine retrieving all my JSON data in a global array..

    }

    @Override
    protected void onPostExecute(Boolean downloadedArray) 
    {
        super.onPostExecute(downloadedArray);
    }
}

問題は、UI でマルチスレッドを作成していることですが、ループ スレッドを削除して、Asynctask の onPostExecute() メソッドだけに置き換える方法を誰かに教えてもらえますか?? (待機させるよりも、asynctask の終了を待機する方がよい場合があります..)

または、マルチスレッドでこのバグを修正するのに役立つかもしれません..

編集 :

私の非同期タスク:

public class DownloadAnnouncers extends AsyncTask<Void, Integer, Boolean>
    {
        public static Boolean loadFinished = false;

        //JSON variables..


        private static String url = null;

        Context context;

        public DownloadAnnouncers(Context context) 
        {
            this.context = context;
        }

        @Override
        protected void onPreExecute() 
        {
            super.onPreExecute();
        }

        protected Boolean doInBackground(Void... params) 
        {

        // fine retrieving all my JSON data in a global array..

        }

        @Override
        protected void onPostExecute(Boolean downloadedArray) 
        {
            super.onPostExecute(downloadedArray);
        Intent intent_to_tabhost = new Intent(context, MyTabActivity.class);
        intent_to_tabhost.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent_to_tabhost);
        }
    }

しかし、キャンセルボタンを押すと、スプラッシュスクリーンアクティビティに戻ります..そして、 onPostExecute メソッドで ctx.finish() を実行できません..

4

2 に答える 2

1

エラー メッセージが示すように、 をHandler呼び出していないスレッド内に を作成することはできません。Looper.prepare()

Looper.prepare() を呼び出していないスレッド内でハンドラーを作成できません

Handler は 内で作成されるためAsyncTask、最初は目にするものではありません。

コードをそのまま保持したい場合は、AsyncTask の作成をカスタム スレッドの外に移動して修正します。

ただし、スレッドを作成する必要はありません。UI スレッドで AsyncTask を作成するだけで (独自のスレッドで実行されるため、作業中に電話がロックされることはありません)、その後必要なアクションを実行できます。 -メソッドでタスクは完了onPostExecuteです。

class ExampleAsync extends AsyncTask<Void, Integer, Boolean>
{
    public static Boolean loadFinished = false;
    //JSON variables..
    private static String url = null;
    Context context;

    public DownloadAnnouncers(Context context){
        this.context = context;
    }

    protected Boolean doInBackground(Void... params){
        // fine retrieving all my JSON data in a global array..
    }

    @Override
    protected void onPostExecute(Boolean downloadedArray){
        Intent intent_to_tabhost = new Intent(context, MyTabActivity.class);
        startActivity(intent_to_tabhost);
    }
}

そしてあなたの活動で:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.splashscreen_second);
    AsyncTask myTask = new ExampleAsync(this);
    myTask.execute();
}
于 2013-02-10T13:50:05.140 に答える
0

asyncTask を待つ代わりに、タスクが終了した後にのみ UI スレッドで呼び出される onPostExecute を使用します。

アクティビティが破棄された場合 (たとえば、スプラッシュ スクリーンが表示されている間にユーザーが戻るボタンを押した場合) にも、タスクをキャンセルする必要があります。

于 2013-02-10T13:53:57.307 に答える