0

アクティビティをダイアログとして使用します(問題はないと思いますが、言及します)。

そのダイアログはユーザーからデータをApache's HttpClient取得し、そのデータを Web サービスに送信します。これは、Button と、その Button に関連付けられた onClick() メソッドを取得したことを意味します。onClick()ユーザーが追加したデータを取得して、JSON として送信するメソッド ( sendJSON という名前) に渡します

次に、スレッドのコードを追加しました。AsyncTask を拡張してデータをパラメーターとして渡し、内部でsendJSONメソッドdoInBackgroundを呼び出し、 onClick 内でユーザー データをパラメーターとして呼び出すだけです。execute()

Google で検索した内容から、メソッドを呼び出すことができるようにアクティビティを呼び出すというエラーが表示されますsendJSON。そして、これは次のとおりです。

Do not access the Android UI toolkit from outside the UI thread

というわけで、2つ質問させていただきました。この問題のクイックフィックスは何ですか? runOnUiThreadonClick() メソッド内で作業を行いますか? 次に、最初から私のロジックのどこが間違っていたのでしょうか? 必要なメソッドの構築を開始し、スレッドのコードを追加しました。では、最初からどう考えればよかったのでしょうか。

考え、コードを書き、検索して何が問題なのかを理解するのに何時間もかかりました。そのため、そこから何を学ぶべきかを知り、同じエラーを繰り返さないようにしたいだけです。

ありがとうございました

編集:コード

onClick :

    @Override
public void onClick(View v) {

       if( v == send ) {


            //Mocking data
            String  network="anetwork", password    , comment;
            String lat="1", longt="2";

            EditText passwd = (EditText)findViewById(R.id.password);
            password = passwd.getText().toString();

            EditText com = (EditText)findViewById(R.id.comment);
            comment = com.getText().toString();


            LongSend ls = new LongSend();
            ls.execute(lat,longt,network,password,comment);

         }
    }

AsyncTask :

public class LongSend extends AsyncTask<String, Void, Void> {

    @Override
    protected Void doInBackground(String... params){
        Log.i("AsyncTask", "here 1");

        int param1 = Integer.parseInt(params[0]);
        int param2 = Integer.parseInt(params[1]);

        DialogActivity da = new DialogActivity();
        try {
            da.sendJson(param1, param2, params[2], params[3], params[4]);
        } catch (JSONException e) {
            e.printStackTrace();
        }           

        return null;
    }


    @Override
    protected void onPreExecute() {

    }


    @Override
    protected void onPostExecute(Void nothing) {
        //              
    }

}

sendJSON

public void sendJson( int lat, int longt,  String network, String passwd, String comment )  throws JSONException {

    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("web_service_here");   
    HttpResponse response;

    JSONObject json = new JSONObject();
    JSONObject nested = new JSONObject();

        try { 
                Log.i("SENDJSON", " print");

                nested.put("lat", lat);
                nested.put("longt", longt);

                json.put("coord", nested);      //add "nested" to "json"

                json.put("network", network);
                json.put("password", passwd);
                json.put("comment", comment);

                StringEntity se = new StringEntity(json.toString());
                se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));

                httppost.getParams().setParameter("json", json);

                Log.v("sendJSON", "json== " +json);

                httppost.setEntity(se);
                Log.v("sendJSON", "SE== " +se);

                response = httpclient.execute(httppost);

                if(response !=null) {

                        str = inputStreamToString(response.getEntity().getContent()).toString();

                        Log.i("POST", "send JSON data");
                        Log.i("DATA", "Data Send==" +str );

                }

        } catch ( ClientProtocolException e ) {
            e.printStackTrace();
        } catch ( IOException  e) {
            e.printStackTrace();
        }


}

アクティビティ

public class DialogActivity  extends Activity implements OnClickListener {

public static String str;
Button send;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.dialog_fragment);


    send =  (Button)findViewById(R.id.button_send);
    send.setOnClickListener(this);


}

LogCat :

06-08 05:33:59.801: E/AndroidRuntime(397): 致命的な例外: AsyncTask

1 06-08 05:33:59.801: E/AndroidRuntime(397): java.lang.RuntimeException: 実行中にエラーが発生しました

doInBackground() 06-08 05:33:59.801: E/AndroidRuntime(397): android.os.AsyncTask$3.done(AsyncTask.java:266) 06-08 05:33:59.801: E/AndroidRuntime(397) : java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 06-08 05:33:59.801: E/AndroidRuntime(397): java.util.concurrent.FutureTask.setException(FutureTask.java) :124) 06-08 05:33:59.801: E/AndroidRuntime(397): java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 06-08 05:33:59.801: E/AndroidRuntime (397): java.util.concurrent.FutureTask.run(FutureTask.java:137) 06-08 05:33:59.801: E/AndroidRuntime(397): java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor. java:1081) 06-08 05:33:59.801: E/AndroidRuntime(397): java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:574) 06-08 05:33:59.801: E/AndroidRuntime(397): java.lang.Thread.run(Thread.java:1020) 06-08 05:33:59.801: E/AndroidRuntime(397): 原因by: java.lang.RuntimeException: 06-08 05:33:59.801: E/AndroidRuntime(397): at android.os.Handler.(Handler. java:121) 06-08 05:33:59.801: E/AndroidRuntime(397): android.app.Activity.(Activity.java:727) 06-08 05:33:59.801: E/AndroidRuntime(397): org.teo.wifit.DialogActivity.(DialogActivity.java:30) 06-08 05:33:59.801: E/AndroidRuntime(397): org.teo.wifit.DialogActivity$LongSend.doInBackground(DialogActivity.java:88) ) 06-08 05:33:59.801: E/AndroidRuntime(397): org.teo.wifit.DialogActivity$LongSend.doInBackground(DialogActivity.java:1) 06-08 05:33:59.801: E/AndroidRuntime(397 ):android.os.AsyncTask$2.call(AsyncTask.java:252) 06-08 05:33:59.801: E/AndroidRuntime(397): java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) ) 06-08 05:33:59.801: E/AndroidRuntime(397): ... 4 以上

問題がある88行目: DialogActivity da = new DialogActivity();

4

3 に答える 3

1

Android デベロッパーガイドを確認して読む

これは、Android UI ツールキットがスレッドセーフではないことを示しています。したがって、シングル スレッド モデルにより、UI が異なるスレッドによって同時に変更されることはありません。

アプリがユーザーの操作に応じて集中的な作業を実行する場合、アプリケーションを適切に実装しない限り、このシングル スレッド モデルではパフォーマンスが低下する可能性があります。具体的には、UI スレッドですべてが発生している場合、ネットワーク アクセスやデータベース クエリなどの長時間の操作を実行すると、UI 全体がブロックされます。スレッドがブロックされると、描画イベントを含め、イベントをディスパッチできなくなります。ユーザーの観点からは、アプリケーションがハングしているように見えます。さらに悪いことに、UI スレッドが数秒以上 (現在は約 5 秒) ブロックされている場合、ユーザーには悪名高い「アプリケーションが応答していません」(ANR) ダイアログが表示されます。その後、ユーザーはアプリケーションを終了し、不満がある場合はアンインストールすることを決定する可能性があります。

さらに、Andoid UI ツールキットはスレッドセーフではありません。したがって、ワーカー スレッドから UI を操作してはなりません。UI スレッドからユーザー インターフェイスに対するすべての操作を行う必要があります。したがって、Android のシングル スレッド モデルには 2 つのルールがあります。

UI スレッドをブロックしない UI スレッドの外部から Android UI ツールキットにアクセスしない

于 2013-06-08T04:40:31.517 に答える