3

クライアントがサーバーにリクエストを送信したときに進行状況ダイアログを表示したい..リクエストはバックグラウンドで実行する必要があります...しかし、AsyncTaskを使用すると強制終了します..助けてください..ありがとう

package com.example.client;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    public static ProgressDialog Dialog;
    String s1;

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

        findViewById(R.id.button1).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // sendreq();
                new SendUserTask().execute();
            }
        });
    }

    public String sendreq() {
        try {
            // TODO Auto-generated method stub
            SocketAddress sockaddr = new InetSocketAddress("192.168.7.116",
                    9011);
            Socket serversocket = new Socket();
            serversocket.connect(sockaddr, 10000);
            serversocket.setSoTimeout(10000);

            DataOutputStream out = new DataOutputStream(
                    serversocket.getOutputStream());
            out.flush();

            DataInputStream in = new DataInputStream(
                    serversocket.getInputStream());
            out.flush();
            String msg = "";

            msg = "hi";
            out.writeBytes(msg);
            out.flush();
            byte[] message = new byte[100];
            in.read(message);
            s1 = new String(message);
            Toast.makeText(getApplicationContext(), s1, Toast.LENGTH_LONG)
                    .show();

            ((TextView) findViewById(R.id.textView1)).setText(s1);
            in.close();
            out.close();
            serversocket.close();
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(), String.valueOf(e),
                    Toast.LENGTH_LONG).show();
        }
        return null;
    }

    private class SendUserTask extends AsyncTask<Void, Void, String> {

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            Dialog = ProgressDialog.show(MainActivity.this, "",
                    "Logging In....", true);

            super.onPreExecute();
        }

        protected void onPostExecute(String s) {

            if (Dialog.isShowing())
                Dialog.dismiss();
        }

        @Override
        protected String doInBackground(Void... params) {
            // TODO Auto-generated method stub
            try {
                return sendreq();

            } catch (Exception e) {
                Toast.makeText(getApplicationContext(), String.valueOf(e),
                        Toast.LENGTH_SHORT).show();
            }
            return null;
        }
    }

}
4

3 に答える 3

3

これ((TextView) findViewById(R.id.textView1)).setText(s1);はバックグラウンド スレッドから実行されます。UI スレッド外の UI 要素にアクセスすることはできません。

その部分を onProgressUpdate または onPostExecute に移動するか、runOnUiThread Runnable で実行する必要があります。

于 2012-10-08T14:32:30.820 に答える
0

doInBackgorund()非UIスレッドであり、その中のUI要素にアクセスすることはできません。doInBackground()内のコードは、レイアウトで定義されたUI要素にアクセスできない別の非UIスレッドで実行されます。また、インテントを介して別のアクティビティを呼び出すため、アクティビティはUIスレッドで実行されるため、UI以外のスレッド内から別のアクティビティを開始しないように常に注意する必要があります。

したがって、doInBackground()の内部からUI要素にアクセスするコード " ((TextView) findViewById(R.id.textView1)).setText(s1);"を削除し、代わりに、内部に配置しますonPostExecute()。これはUIスレッドであり、doInBackground()がバックグラウンド処理を終了した後に呼び出されます。

于 2012-10-08T16:20:35.900 に答える
0

わかりました....たくさんグーグルした後、メインスレッドから新しい非UIスレッドにUI要素にアクセスできないことを最終的に理解するようになりました....したがって、textviewやgetApplicationContext mtd tht v use for toastなどの要素を使用することはできませんdobackground mtd または dobackground が呼び出している他の mts でさえ....これは、runnable を使用する新しい Thread() にも適用されます..njzk2 さん、助けてくれてありがとう :)

于 2012-10-09T09:16:53.573 に答える