如何使用AsyncTask

Kev*_*gem 6 java multithreading android android-asynctask

AsyncTask问题

我已经按照一些教程,但我仍然不清楚.这是我目前的代码,代码下面有一些问题.MainActivity调用SomeClassWithHTTPNeeds,然后调用JSONParser(AsyncTask <>)


主要活动:

String station = SomeClassWithHTTPNeeds.getInstance().getStation(123);
Run Code Online (Sandbox Code Playgroud)

SomeClassWithHTTPNeeds:

getStation {

JSONParser = new JSONParser();
JSONObject station = parser.getJSONFromUrl("https://api....");
return JSONObject.getString("station");
}
Run Code Online (Sandbox Code Playgroud)

JSONParser(AsyncTask <String,Void,String>)

protected String doInBackground(); ==> Seperate thread
protected void onPostExecute(); ==> On GUI thread
Run Code Online (Sandbox Code Playgroud)

我在想:---把HTTPRequest放在doInBackground()中;

问题是我不知道如何:让JSONParser将JSONObject返回到getStation方法?

我需要知道的

=>我应该在哪里返回JSONObject:在后台还是执行?

=>一旦它是AsyncTask,我如何使用JSONParser?execute()函数会返回值吗?

=> AsyncTask <String,Void,String> ==>这是如何工作的?这是回归类型?

非常感谢!

Phi*_*oda 16

常见问题和AsyncTask使用的一般说明

=>我应该在哪里进行网络操作?我应该在哪里归还我所获得的价值观?

通常,您应该在单独的线程中执行网络操作- > doInBackground(); 因为您不希望在网络操作占用时间时冻结UI.因此,您应该连接到Service或.php脚本,或者从doInBackground()方法内部获取数据的任何位置.然后你也可以解析那里的数据并doInBackground()通过指定doInBackground()你想要的返回类型来返回方法中的解析数据,更多关于那里的数据.onPostExecute()然后,该方法将从doInBackground()UI 接收您返回的值并使用UI表示它们.

=> AsyncTask <String,Integer,Long> ==>这是如何工作的?

通常,AsyncTask类看起来像这样,它只不过是具有3种不同泛型类型的泛型类:

AsyncTask<Params, Progress, Result>
Run Code Online (Sandbox Code Playgroud)

您可以指定参数的AsyncTask类型,进度指示器的类型和结果的类型(doInBackGround()的返回类型).

这是一个AsyncTask看起来像这样的例子:

AsyncTask<String, Integer, Long>
Run Code Online (Sandbox Code Playgroud)

我们有参数的类型字符串,进度的类型整数和结果的类型长(返回类型doInBackground()).您可以使用Params,Progress和Result所需的任何类型.

private class DownloadFilesTask extends AsyncTask<String, Integer, Long> {

 // these Strings / or String are / is the parameters of the task, that can be handed over via the excecute(params) method of AsyncTask
 protected Long doInBackground(String... params) {

    String param1 = params[0];
    String param2 = params[1];
    // and so on...
    // do something with the parameters...
    // be careful, this can easily result in a ArrayIndexOutOfBounds exception
    // if you try to access more parameters than you handed over

    long someLong;
    int someInt;

    // do something here with params
    // the params could for example contain an url and you could download stuff using this url here

    // the Integer variable is used for progress
    publishProgress(someInt);

    // once the data is downloaded (for example JSON data)
    // parse the data and return it to the onPostExecute() method
    // in this example the return data is simply a long value
    // this could also be a list of your custom-objects, ...
    return someLong;
 }

 // this is called whenever you call puhlishProgress(Integer), for example when updating a progressbar when downloading stuff
 protected void onProgressUpdate(Integer... progress) {
     setProgressPercent(progress[0]);
 }

 // the onPostexecute method receives the return type of doInBackGround()
 protected void onPostExecute(Long result) {
     // do something with the result, for example display the received Data in a ListView
     // in this case, "result" would contain the "someLong" variable returned by doInBackground();
 }
}
Run Code Online (Sandbox Code Playgroud)

=>如何使用AsyncTask?我怎么称呼它呢?我怎样才能"执行"它?

在这种情况下,AsyncTask将String或String Array作为参数,一旦调用AsyncTask,它将如下所示:( 指定的参数用于AsyncTask的execute(param)方法).

new DownloadFilesTask().execute("Somestring"); // some String as param
Run Code Online (Sandbox Code Playgroud)

请注意,此调用没有返回值,您应该使用的唯一返回值是从中返回的值doInBackground().使用onPostExecute()方法确实可以使用返回的值.

这一行代码也要小心:(这个执行实际上会有一个返回值)

long myLong = new DownloadFilesTask().execute("somestring").get();
Run Code Online (Sandbox Code Playgroud)

当AsyncTask正在执行时,.get()调用会导致UI线程被阻塞(因此,如果操作花费的时间超过几毫秒,UI会冻结),因为执行不会在单独的线程中执行.如果删除对.get()的调用,它将异步执行.

=>这种符号"执行(String ... params)"是什么意思?

这是一个带有所谓" varargs "(变量参数)参数的方法.为了简单起见,我只想说这意味着你没有指定你可以通过这个参数传递给方法的实际值的数量,并且你给方法的任何数量的值都将被视为一个数组内的数组.方法.所以这个调用可能是这样的:

execute("param1");
Run Code Online (Sandbox Code Playgroud)

但它也可能看起来像这样:

execute("param1", "param2");
Run Code Online (Sandbox Code Playgroud)

甚至更多的参数.假设我们还在讨论AsyncTask,可以在方法中以这种方式访问​​参数doInBackground(String... params):

 protected Long doInBackground(String... params) {

     String str1 = params[0];
     String str2 = params[1]; // be careful here, you can easily get an ArrayOutOfBoundsException

     // do other stuff
 }
Run Code Online (Sandbox Code Playgroud)

您可以在此处阅读有关AsyncTask的更多信息:http://developer.android.com/reference/android/os/AsyncTask.html

另请参阅此AsyncTask示例:https://stackoverflow.com/a/9671602/1590502