4

postexecute()でAlertDialogを実行する際に問題が発生しました。この例外をスローします原因:java.lang.RuntimeException:Looper.prepare()を呼び出さなかったスレッド内にハンドラーを作成できません。または、AlertDialog.Builderを配置したときに、Plsヘルプが機能しませんでした。また、間違ったパスワードが入力された場合、プロセスは終了します。使用名またはパスワードが無効な場合にToastメソッドを呼び出すにはどうすればよいですか?以下はコードスニペットです

public void Login() {

    // Toast.makeText(getBaseContext(), pass.getText() + " "
    // +user.getText(),
    // Toast.LENGTH_SHORT).show();

    String url = "http://107.20.195.151/mcast_ws/" + "?user="
            + user.getText().toString() + "&password="
            + pass.getText().toString();

    result = getHttpResponse(url);  
}


String result;
private String getHttpResponse(String location) {
    result = "";
    URL url = null;
    Log.d(LOGTAG, " " + "location " + location);
    try {
        url = new URL(location);
    } catch (MalformedURLException e) {
        Log.e(LOGTAG, " " + "error" + e.getMessage());
    }
    if (url != null) {
        try {
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String inputLine;
            int lineCount = 0;
            while ((inputLine = in.readLine()) != null) {
                result += inputLine.trim();
            }

            in.close();
            connection.disconnect();
        } catch (Exception e) {

            Log.e(LOGTAG, " " + "IOError " + e.getMessage());
            Toast.makeText(getBaseContext(), "No Internet Access",
                    Toast.LENGTH_SHORT);
        }
    } else {
        Log.e(LOGTAG, " " + "url" + url);
    }
    return result;
}

class PostToTwitter extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {

        Login();
        Log.d(LOGTAG, "Success");
        Log.d(LOGTAG, result);
        Log.d(LOGTAG, result.substring(0, 16).trim());
        // Log.d(TweetActivity.getLogtag(),"Successfully Posted: " +
        // params[0]);

        return "success";
    }

    @Override
    protected void onPostExecute(String r) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        String msg = "Login successful";

        if (result.substring(0, 16).trim().equals(msg)) {
            // System.out.println(result.substring(0, 16).trim());
            Log.d(LOGTAG, " " + "Connection Test" + result);
            AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
            builder.setMessage("Are you sure send this SMS?")
                   .setCancelable(false)
                   .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                       public void onClick(DialogInterface dialog, int id) {
                            //...Attach another thread event to send the sms
                       }
                   })
                   .setNegativeButton("No", new DialogInterface.OnClickListener() {
                       public void onClick(DialogInterface dialog, int id) {
                            dialog.cancel();
                       }
                   });
            Log.e(LOGTAG, "Error detected 2");
            AlertDialog alert = builder.create();
            alert.show();
            //return  "success";
            // Toast.makeText(getBaseContext(),
            // "Login Succesful",Toast.LENGTH_SHORT).show();

        } else {
            Toast.makeText(getBaseContext(),
                    "Login UnSuccesful. Check Username or password",
                    Toast.LENGTH_SHORT).show();
            //return null;
        }
        // Toast.makeText(getApplicationContext(), result
        // ,Toast.LENGTH_SHORT).show();
        Log.e(LOGTAG, "Error detected");

        /*
        Intent i = new Intent("com.sms.subsahara.COMPOSESMS");
        startActivity(i);
        //Log.e(LOGTAG, " " + "error2");*/

    }

}

Alexからの提案を適用すると、上記の元のコードを変更しましたが、それでもエラーが発生します。以下はlogcatからの例外です。

E/AndroidRuntime(  326): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime(  326): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
E/AndroidRuntime(  326):        at android.view.ViewRoot.setView(ViewRoot.java:472)
E/AndroidRuntime(  326):        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
E/AndroidRuntime(  326):        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/AndroidRuntime(  326):        at android.app.Dialog.show(Dialog.java:239)
E/AndroidRuntime(  326):        at com.sms.subsahara.WebMessengerActivity$PostToTwitter.onPostExecute(WebMessengerActivity.java:216)
E/AndroidRuntime(  326):        at com.sms.subsahara.WebMessengerActivity$PostToTwitter.onPostExecute(WebMessengerActivity.java:1)
E/AndroidRuntime(  326):        at android.os.AsyncTask.finish(AsyncTask.java:417)
E/AndroidRuntime(  326):        at android.os.AsyncTask.access$300(AsyncTask.java:127)
E/AndroidRuntime(  326):        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
E/AndroidRuntime(  326):        at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(  326):        at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(  326):        at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime(  326):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(  326):        at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime(  326):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime(  326):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime(  326):        at dalvik.system.NativeStart.main(Native Method)
4

4 に答える 4

8

doInBackgroundは UI スレッドと同期されません。つまり、メソッド内から UI 要素を直接操作したり、ダイアログを起動したりすることはできません。修正は簡単です。AlertDialogコードをonPostExecuteメソッドに移動するだけです (UI スレッド同期されます)。

AsyncTasks を使用するときは、次のことに注意してください。

  1. doInBackgroundコストがかかる可能性のある操作 (ネットワーク アクセス、ソケット接続、データベース クエリなど) を実行するためのものです。
  2. onPostExecute必要に応じて、結果を処理するためのものです (このメソッドは UI スレッドと同期されるため、UI 要素を直接操作できます)。
于 2012-06-27T03:27:30.800 に答える
3

DoInBackground() は、メイン UI スレッドとは異なるスレッドでのみ実行されます。それが AsyncTask の要点です。

結果を UI に投稿する方法は 3 つあります (ほとんど... UI スレッドに)。

  1. onPostExecute メソッドを使用します。渡された doInBackground メソッドの戻り値を取得し、それを使って何でもできます。(これはあなたのユースケースに合っていると思います。)

  2. タスクが進行中で、プログレス バーの更新など、UI に情報のバーストが必要な場合は、doInBackground メソッドの publishProgress(...) を使用します。これは onProgressUpdate(...) メソッドに渡されます。 UIスレッドで実行されるAsyncTaskで。

  3. 2 と同様ですが、RunOnUiThread(...) コンビニエンス メソッドを使用して、UI スレッドで実行する runnable をスローできます。複数の匿名メソッドが浮かんでいる場合、最も美しいコードではないかもしれませんが、それを行うための迅速で汚い方法です。このメソッドは、Activity クラスでは使用できますが、Context クラスでは使用できないことに注意してください。

于 2012-06-27T03:53:24.740 に答える
1

Login () が実行中の mainUI ではなく、実行中の AsyncTask にあるためだと思います。onPostExecute ハンドラを内部で実行して、メイン スレッドの実行に戻すことができます。onPostExecute UIThread でも使用できます。

runOnUiThread(new Runnable() {
                 @Override
                    public void run() {
                    Login();    
                   }
                });

お役に立てば幸いです。

于 2012-06-27T03:20:39.513 に答える