【问题标题】:network operation without asyncTask in AndroidAndroid中没有asyncTask的网络操作
【发布时间】:2014-12-07 11:47:59
【问题描述】:

我可以使用 AsyncTask 成功连接到我的 servlet 服务器,但现在我决定我想要一个进度对话框,让用户知道正在进行网络操作。 (使用 2G 有时 3G 我可以注意到获取结果的延迟)。 我的问题是在尝试执行此操作时 AsyncTask 崩溃时开始的:

private class GetQinfo extends AsyncTask<String, Void,String> {
            ProgressDialog progDailog ;
             protected void onPreExecute() {
                    super.onPreExecute();
                    progDailog= new ProgressDialog(GetTicket.this);
                    progDailog.setMessage("pls wait");
                    progDailog.setIndeterminate(false);
                    progDailog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                    progDailog.setCancelable(true);
                    progDailog.show();
                }    
        protected String doInBackground(String... arg0) {...}
        protected void onPostExecute(String branchQ){
         ...
         progDailog.dismiss();
        }
}

但这给了我一个例外

 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

所以我决定停止使用 AsyncTask,因为我真的不需要它(我想)。由于我不允许用户在 UI 上做任何事情,使用 AsyncTask 有什么意义吗? 我选择了线程解决方案:

        new Thread(new Runnable() {
            public void run() {
             String line=null;
             try {
                    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
                nameValuePairs.add(new BasicNameValuePair("command", "GetQ"));
                 nameValuePairs.add(new BasicNameValuePair("city", city));
                 nameValuePairs.add(new BasicNameValuePair("type", type));
                 nameValuePairs.add(new BasicNameValuePair("org", org));
                 nameValuePairs.add(new BasicNameValuePair("branch", spinner.getSelectedItem().toString()));
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,"utf-8"));

                 // Execute HTTP Post Request
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity ht = response.getEntity();
                BufferedHttpEntity buf = new BufferedHttpEntity(ht);
                InputStream is = buf.getContent();
                BufferedReader r = new BufferedReader(new InputStreamReader(is));

              line = r.readLine();
               nameValuePairs.clear();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                line="-1";
            }

            String[] info=line.split(";");
            if(info[1].equals("-1")){
                Toast.makeText(getApplicationContext(), "Some msg", Toast.LENGTH_LONG).show();
            }
            else{
                 ....
                //Update the UI
                 }
          }
          }).start();

但由于某种原因,这引发了 java.net.SocketException: Socket closed on this line HttpResponse 响应 = httpclient.execute(httppost); 有任何想法吗?谢谢

编辑: @Ahmad Dwaik '术士' 我确实从主线程调用它,我有一个微调器和一个方法

public void onItemSelected(AdapterView<?> arg0, View arg1,
             int arg2, long arg3) {
       if(arg2==0){
            //no selection
            }
        else{
new GetQinfo().execute(city,type,org,spinner.getSelectedItem().toString());
}

通过执行这个我得到 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 错误。日志是

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
12-07 10:16:19.285: E/AndroidRuntime(1929):     at android.os.Handler.<init>(Handler.java:200)
12-07 10:16:19.285: E/AndroidRuntime(1929):     at android.os.Handler.<init>(Handler.java:114)
12-07 10:16:19.285: E/AndroidRuntime(1929):     at android.app.Dialog.<init>(Dialog.java:109)
12-07 10:16:19.285: E/AndroidRuntime(1929):     at android.app.AlertDialog.<init>(AlertDialog.java:114)
12-07 10:16:19.285: E/AndroidRuntime(1929):     at android.app.AlertDialog.<init>(AlertDialog.java:98)
12-07 10:16:19.285: E/AndroidRuntime(1929):     at android.app.ProgressDialog.<init>(ProgressDialog.java:77)
12-07 10:16:19.285: E/AndroidRuntime(1929):     at com.example.quecustomer.GetTicket$GetQinfo.onPreExecute(GetTicket.java:872)
12-07 10:16:19.285: E/AndroidRuntime(1929):     at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587)
12-07 10:16:19.285: E/AndroidRuntime(1929):     at android.os.AsyncTask.execute(AsyncTask.java:535)
12-07 10:16:19.285: E/AndroidRuntime(1929):     at com.example.quecustomer.GetTicket$1.run(GetTicket.java:781)
12-07 10:16:19.285: E/AndroidRuntime(1929):     at java.lang.Thread.run(Thread.java:841)

GetTicket.java:872 指的是这一行:

 progDailog= new ProgressDialog(GetTicket.this);

我的背景: @

Override
            protected String doInBackground(String... arg0) {
                try {
                        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
                    nameValuePairs.add(new BasicNameValuePair("command", "GetQ"));
                    nameValuePairs.add(new BasicNameValuePair("city", arg0[0]));
                    nameValuePairs.add(new BasicNameValuePair("type", arg0[1]));
                    nameValuePairs.add(new BasicNameValuePair("org", arg0[2]));
                    nameValuePairs.add(new BasicNameValuePair("branch", arg0[3]));
                    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,"utf-8"));
                    // Execute HTTP Post Request
                    HttpResponse response = httpclient.execute(httppost);
                    HttpEntity ht = response.getEntity();
                    BufferedHttpEntity buf = new BufferedHttpEntity(ht);
                    InputStream is = buf.getContent();
                    BufferedReader r = new BufferedReader(new InputStreamReader(is));
                   String line = r.readLine();
                   nameValuePairs.clear();
                   return line;
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return null;
            }

编辑 2 事实证明我找到了解决方法,但不确定它是否正确。很好用,所以它一定是:)

我使用 onProgressUpdate(Void...none) 创建 ProgressDialog 并在 onPostExecute() 上将其关闭。 你怎么看?

【问题讨论】:

    标签: android android-asynctask


    【解决方案1】:

    您的堆栈跟踪显示您在此处从另一个Thread 调用AsyncTask

    12-07 10:16:19.285: E/AndroidRuntime(1929):     at com.example.quecustomer.GetTicket$1.run(GetTicket.java:781)
    12-07 10:16:19.285: E/AndroidRuntime(1929):     at java.lang.Thread.run(Thread.java:841)
    

    查看GetTicket 的第 781 行。你可能会打电话给new GetQinfo.execute(),它会带你去:

    12-07 10:16:19.285: E/AndroidRuntime(1929):     at com.example.quecustomer.GetTicket$GetQinfo.onPreExecute(GetTicket.java:872)
    

    【讨论】:

    • !!我从两个不同的地方调用这个 AsyncTask。一个是线程,另一个来自线程。那么这是什么意思呢?我不能从调用异步任务的线程调用进度对话框?
    • 不,你不能。您应该只从 UI Thread 调用 AsyncTask
    【解决方案2】:

    关于这个错误,你没有提供太多细节

    java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    

    您似乎没有从主“UI”线程中调用您的 AsyncTask new GetQinfo().execute(args);

    再次考虑使用 AsyncTask,很好地实现它并直接从主线程中调用它。如果那没有帮助显示您的完整 AsyncTask 子类和完整 logcat

    【讨论】:

    • 请发布您的 doInBackground() 实现
    猜你喜欢
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多