1

私は例外を取得している 1 つのアプリケーションを開発しています。これは私がやっているばかげた、または小さな間違いであることはわかっていますが、あなたの助けが私を見つけて一日を過ごすかもしれません:

public class Demo extends Activity
{
    Button btnDemo;
        Thread t;
    AlertDialog alertDialog;

     @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.demo);

              btnDemo = (Button) findViewById(R.id.btnDemo);
          btnDemo.setOnClickListener(new OnClickListener() {
                      public void onClick(final View v) {

                          t=new Thread() {
                               public void run() {
                                    tryDemo();
                               }
                         };
                         t.start(); 
                      }
                });
     }

    public void tryDemo()
    {

          try
         {
              int i = 5;

              if(i == 0 || i == 1)
              {
                    Intent intent_success = new Intent(getApplicationContext(), Main_Activity.class);
                    startActivity(intent_success);
              }
              else
              {
                alertDialog = new  AlertDialog.Builder(getApplicationContext()).create();
                alertDialog.setTitle("Demo");
                alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int which) {
                       //here you can add functions
                } }); 
                alertDialog.setIcon(R.drawable.icon);
                alertDialog.setMessage("Sorry!! Either Username or Password Invalid");
                alertDialog.show();

              }
         }
         catch(Exception e)
         {
               Log.i("Demo", "Demo - Demo Exception");
         }
    }   
}

上記のコードでは、tryDemo 関数で i=0 または i=1 にすると正常に実行されますが、0 または 1 以外にすると "Demo - Demo Exception" として例外がスローされます

よくわかりませんが、 getApplicationContext()から例外が発生すると思います。

更新:- 1

次のように、私が取得している例外:

代替テキスト

更新:- 2 「スレッド」部分を削除し、ボタン クリック イベントに関数コード全体を記述し、「getApplicationContext()」を v.getContext() に置き換えた場合、正常に実行されます........ .しかし、THREAD内に実装したい。

私を助けて、私を捕まえてください...

ありがとう

4

4 に答える 4

1

この投稿のチェックアウトコメント:

どこでもアプリケーションコンテキストを使用していますか?

また、getApplicationContext()をactiivtyname.getApplicationContext()に置き換えると、どのようなエラーが発生しますか?

于 2010-09-09T14:13:55.873 に答える
1

ログを読んでください:D Looper.prepare()を呼び出していません

私が正しければ、AlertDialogコードをLooper.prepare()とLooper.loop()でラップする必要があります

したがって、次のようになります。

Looper.prepare()
// AlertDialog code
Looper.loop()
于 2010-09-09T09:11:25.193 に答える
1

あなたはおそらくRuntimeException. UIスレッドではないスレッドでダイアログの作成を呼び出してみたところ、次のようになりました。

09-09 00:46:37.702: ERROR/AndroidRuntime(763): Uncaught handler: thread Thread-10 exiting due to uncaught exception
09-09 00:46:37.724: ERROR/AndroidRuntime(763): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.os.Handler.<init>(Handler.java:121)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.view.ViewRoot.<init>(ViewRoot.java:192)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.view.Window$LocalWindowManager.addView(Window.java:392)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.app.Dialog.show(Dialog.java:231)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at com.pkg.name.ToplistActivity$3.run(ToplistActivity.java:149)

解決策は、else ステートメントを次のようにラップすることです。

else {
    runOnUiThread(new Runnable() {
        public void run() {
            ...
        }
    });
}
于 2010-09-09T08:00:00.793 に答える
1

これにはいくつか問題があります。まず、作成したスレッドの UI 要素には絶対に触れないでください。

スレッド Handlers に慣れる必要があります: http://developer.android.com/reference/android/os/Handler.html

それらが機能する方法は、通常の UI スレッドで初期化することです。(onCreate() メソッドが呼び出されるスレッド。) ハンドラは、スレッド間で通信するために拡張するスレッド セーフなオブジェクトです。

だから、あなたの onCreate() で:

Handler pHandler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            Bundle bundle = msg.getData();
            int msg_type = bundle.getInt("TYPE");
            if (msg_type == MyThread.ERROR_MSG)
            {
                 ///SOMETHING HAPPENED
                 return;
            }
            else
            {
                //background task finished ok
            }
        }
    };

次に、run() メソッドから、Bundle および Message オブジェクトを使用してメッセージを送信します。 http://developer.android.com/reference/android/os/Bundle.htmlおよび http://developer.android.com/reference/android/os/Message.html

物事をきれいに保つために私が好きな方法は、 Thread クラスを拡張して少し一貫性を追加することです...

class MyThead extends Thread
{
    public final int ERROR_MSG = 0;
    public final int OK_MSG = 1;
    Handler mHandler;

    MyThread(Handler pHandler)
    {
        mHandler = pHandler;
    }

    @Override
    public void run()
    {
        //send a message back to the ui thread....
        Message msg = new Message();
        Bundle bundle = new Bundle();
        bundle.putInt("TYPE", OK_MSG);
        msg.setData(bundle);
        mHandler.sendMessage(msg);
    }
}

少し凝りたい場合は、UI コードとワーカー スレッド コードを完全に分離します。バックグラウンド タスクに時間がかからない場合は、前述のように runonUiThread() を使用できます。

AsyncTask を使用することもできます。次を参照してください: http://developer.android.com/reference/android/os/AsyncTask.html

これは彼らのページの例です。その使用法はかなり単純です:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

ただし、最終的には、タスクの実行中にユーザーが方向を変更した場合、これらのアプローチは完全ではありません。(または、その他の理由でアクティビティが強制終了された場合。) その場合、サービスをセットアップする必要があります: http://developer.android.com/reference/android/app/Service.html

于 2010-09-10T23:56:04.763 に答える