使用AsyncTask

use*_*898 0 multithreading android httpwebrequest android-asynctask

我是android的新手,我试图从服务器获取一些数据并将其打印在我的设备中.我意识到使用android 4.x我们无法做到这一点因为UI线程被阻止了.我进行了研究,发现了AsyncTask.有人可以帮我一些代码吗?有什么遗失的吗?谢谢

这是我的代码:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    new Thread().execute();        
    openDialog(getCurrentFocus());

}
Run Code Online (Sandbox Code Playgroud)

AsynTask类:

    private class Thread extends AsyncTask<Void, Void, Void> {

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

               //Here i make a HTTP request.

         return null;
    }
   } 
Run Code Online (Sandbox Code Playgroud)

logcat的:

04-22 22:43:10.808: E/Trace(12987): error opening trace file: No such file or directory (2)
04-22 22:43:11.098: E/AndroidRuntime(12987): FATAL EXCEPTION: AsyncTask #1

04-22 22:43:11.098: E/AndroidRuntime(12987): java.lang.RuntimeException: An error occured while executing doInBackground()
04-22 22:43:11.098: E/AndroidRuntime(12987):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at java.lang.Thread.run(Thread.java:856)
04-22 22:43:11.098: E/AndroidRuntime(12987): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-22 22:43:11.098: E/AndroidRuntime(12987):    at android.os.Handler.<init>(Handler.java:197)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at android.os.Handler.<init>(Handler.java:111)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at android.widget.Toast$TN.<init>(Toast.java:324)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at android.widget.Toast.<init>(Toast.java:91)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at android.widget.Toast.makeText(Toast.java:238)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at com.application.uprm_map.MainActivity.startApplication(MainActivity.java:72)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at com.application.uprm_map.MainActivity.access$0(MainActivity.java:67)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at com.application.uprm_map.MainActivity$Thread.doInBackground(MainActivity.java:439)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at com.application.uprm_map.MainActivity$Thread.doInBackground(MainActivity.java:1)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
04-22 22:43:11.098: E/AndroidRuntime(12987):    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
04-22 22:43:11.098: E/AndroidRuntime(12987):    ... 3 more
04-22 22:43:11.413: E/WindowManager(12987): Activity com.application.uprm_map.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{421b4b58 V.E..... R.....I. 0,0-720,412} that was originally added here
04-22 22:43:11.413: E/WindowManager(12987): android.view.WindowLeaked: Activity com.application.uprm_map.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{421b4b58 V.E..... R.....I. 0,0-720,412} that was originally added here
04-22 22:43:11.413: E/WindowManager(12987):     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:354)
04-22 22:43:11.413: E/WindowManager(12987):     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:216)
Run Code Online (Sandbox Code Playgroud)

kad*_*rud 5

我附上了一个使用AsyncTask将参数发布到网页的示例(简化,它应该处理isCancelled一个).您应该根据自己的需要调整它.

AsyncTask用法

必须将AsyncTask子类化才能使用.子类将覆盖至少一个方法(doInBackground(Params ...)),并且通常会覆盖第二个方法(onPostExecute(Result).)

AsyncTask的泛型类型

异步任务使用的三种类型如下:

Params,执行时发送给任务的参数类型.

Progress,后台计算期间发布的进度单元的类型.

Result,背景计算结果的类型.

并非所有类型都始终由异步任务使用.要将类型标记为未使用,只需使用类型Void:

private class MyTask extends AsyncTask<Void, Void, Void> { ... }
Run Code Online (Sandbox Code Playgroud)

这4个步骤

执行异步任务时,任务将执行4个步骤:

  1. onPreExecute(),在执行任务之前在UI线程上调用.此步骤通常用于设置任务,例如通过在用户界面中显示进度条.
  2. doInBackground(Params ...),在onPreExecute()完成执行后立即在后台线程上调用.此步骤用于执行可能需要很长时间的后台计算.异步任务的参数将传递给此步骤.计算结果必须由此步骤返回,并将传递回最后一步.此步骤还可以使用publishProgress(Progress ...)发布一个或多个进度单元.这些值发布在UI线程的onProgressUpdate(Progress ...)步骤中.
  3. onProgressUpdate(Progress ...),在调用publishProgress(Progress ...)后在UI线程上调用.执行的时间是不确定的.此方法用于在后台计算仍在执行时显示用户界面中的任何形式的进度.例如,它可用于为进度条设置动画或在文本字段中显示日志.
  4. onPostExecute(Result),在后台计算完成后在UI线程上调用.背景计算的结果作为参数传递给该步骤.

阅读http://developer.android.com/reference/android/os/AsyncTask.html上有关AsyncTask的更多信息(以上文档中的以上文档)

POST到网页的示例

// (declaration in main class)
private MyNetworkTask mMyNetworkTask = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    String mURL = "http://www.mydomain.com/mycode.php";
    runMyTask(this, mURL);
}

private class MyNetworkTask extends AsyncTask<String, Void, HttpResponse> { // <doInBackground, onProgressUpdate, onPostExecute>

    private ProgressDialog dialog;
    private Context context;

    public MyNetworkTask(Context ctx) {
        context = ctx;
        dialog = new ProgressDialog(context);
    }

    @Override
    protected void onPreExecute() {
        dialog.setMessage("Working ...");
        dialog.show();
    }
    @Override
    protected HttpResponse doInBackground(final String... params) {
        String mURL = params[0];
        HttpParams httpparams = new BasicHttpParams();
        HttpProtocolParams.setContentCharset(httpparams, "UTF-8");

        HttpClient httpclient = new DefaultHttpClient(httpparams);
        HttpPost httppost = new HttpPost(mURL);
        httppost.setHeader("User-Agent", "MyUserAgent/1.0");

        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("param1", "value1"));
        nameValuePairs.add(new BasicNameValuePair("param2", "value2"));
        try {
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            return httpclient.execute(httppost);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
    @Override
    protected void onPostExecute(final HttpResponse result) {
        if (dialog.isShowing()) {
            dialog.dismiss();
        }
        if (result != null) {
            int responseCode = result.getStatusLine().getStatusCode();
            String responseBody="";
            switch(responseCode) {
            case 200:
                HttpEntity entity = result.getEntity();
                if(entity != null) {
                    try {
                        responseBody = EntityUtils.toString(entity);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                break;
            }
            Log.v(TAG, "Response Code => " + responseCode);
            Log.i(TAG, "Response Body => " + responseBody);
        }
    }

    @Override
    protected void onCancelled() {
        if (dialog.isShowing()) {
            dialog.dismiss();
        }
    }
} // AsyncTask

private void runMyTask(Context ctx, String url) {
    if (mMyNetworkTask != null) {
            return;
        }
        mMyNetworkTask = new NetworkTask(this);
        mMyNetworkTask .execute(url);
}
Run Code Online (Sandbox Code Playgroud)