Cod*_*ate 16 android android-asynctask
我会保持这个尽可能简单.
我的控制层中有一个方法,它使用一个CallServiceTask扩展的类AsyncTask.调用new时CallServiceTask().execute(parameters)
如何检索返回的数据doInBackground?我发现的所有教程都使用AsyncTask直接从它们扩展的类Activity.
我的问题比这复杂一点.
我想要的只是将Object[]返回的doInBackground并将其设置为我RestClient班级的私有数据成员.
CallServiceTask 看起来像这样:
private class CallServiceTask extends AsyncTask<Object, Void, Object[]>
{
protected Object[] doInBackground(Object... params)
{
HttpUriRequest req = (HttpUriRequest) params[0];
String url = (String) params[1];
return executeRequest(req, url);
}
}
Run Code Online (Sandbox Code Playgroud)
我的RestClient类看起来像这样:
public class RestClient
{
private ArrayList <NameValuePair> params;
private ArrayList <NameValuePair> headers;
private JSONObject jsonData;
private Object[] rtnData;
private String url;
private boolean connError;
public int getResponseCode() {
return responseCode;
}
/**
*
* @return the result of whether the login was successful by looking at the response parameter of the JSON object.
*/
public Boolean DidLoginSucceed()
{
// Will Crash on socket error
return ((JSONObject) rtnData[0]).optBoolean("response");
}
public String GetToken()
{
return jsonData.optString("token");
}
public RestClient(String url)
{
this.url = url;
params = new ArrayList<NameValuePair>();
headers = new ArrayList<NameValuePair>();
rtnData = new Object[]{ new JSONObject() , Boolean.TRUE };
}
public void AddParam(String name, String value)
{
params.add(new BasicNameValuePair(name, value));
}
public void AddHeader(String name, String value)
{
headers.add(new BasicNameValuePair(name, value));
}
/**
* This method will execute, call the service and instantiate the JSON Object through executeRequest().
*
* @param method an enum defining which method you wish to execute.
* @throws Exception
*/
public void ExecuteCall(RequestMethod method) throws Exception
{
Object[] parameters = new Object[]{ new HttpGet() , new String("") };
switch(method) {
case GET:
{
//add parameters
String combinedParams = "";
if(!params.isEmpty()){
combinedParams += "?";
for(NameValuePair p : params)
{
String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue());
if(combinedParams.length() > 1)
{
combinedParams += "&" + paramString;
}
else
{
combinedParams += paramString;
}
}
}
HttpGet request = new HttpGet(url + combinedParams);
//add headers
for(NameValuePair h : headers)
{
request.addHeader(h.getName(), h.getValue());
}
parameters[0] = request;
parameters[1] = url;
new CallServiceTask().execute(parameters);
jsonData = ((JSONObject) rtnData[0]).optJSONObject("data");
connError = (Boolean) rtnData[1];
break;
}
case POST:
{
HttpPost request = new HttpPost(url);
//add headers
for(NameValuePair h : headers)
{
request.addHeader(h.getName(), h.getValue());
}
if(!params.isEmpty()){
request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
}
new CallServiceTask().execute(request, url);
break;
}
}
}
private Object[] executeRequest(HttpUriRequest request, String url)
{
HttpClient client = new DefaultHttpClient();
client = getNewHttpClient();
HttpResponse httpResponse;
try {
httpResponse = client.execute(request);
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
String response = convertStreamToString(instream);
try {
rtnData[0] = new JSONObject(response);
rtnData[1] = false;
} catch (JSONException e1) {
rtnData[1] = true;
e1.printStackTrace();
}
// Closing the input stream will trigger connection release
instream.close();
}
} catch (ClientProtocolException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
} catch (IOException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
}
return rtnData;
}
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
/**
* Custom HTTP Client accepting all SSL Certified Web Services.
*
* @return n HttpClient object.
*/
public HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
Run Code Online (Sandbox Code Playgroud)
Saa*_*ooq 25
唯一的方法是使用CallBack.你可以这样做:
new CallServiceTask(this).execute(request, url);
Run Code Online (Sandbox Code Playgroud)
然后在你的CallServiceTask中添加一个本地类变量,并在你的onPostExecute中调用该类的方法:
private class CallServiceTask extends AsyncTask<Object, Void, Object[]>
{
RestClient caller;
CallServiceTask(RestClient caller) {
this.caller = caller;
}
protected Object[] doInBackground(Object... params)
{
HttpUriRequest req = (HttpUriRequest) params[0];
String url = (String) params[1];
return executeRequest(req, url);
}
protected onPostExecute(Object result) {
caller.onBackgroundTaskCompleted(result);
}
}
Run Code Online (Sandbox Code Playgroud)
然后只需onBackgroundTaskCompleted()在RestClient类的方法中使用Object .
更优雅和可扩展的解决方案是使用接口.有关示例实现,请参阅此库.我刚刚开始它,但它有一个你想要的例子.
HiB*_*HiB 13
正如@ saad-farooq所提到的,你可以使用接口.所以你可以使用Handler.Callback或定义你自己的:
public interface ClientIF {
public void onResponseReceived(Object result);
}
Run Code Online (Sandbox Code Playgroud)
那么你需要在你的CallServiceTask中实现它
public abstract class CallServiceTask extends AsyncTask<Object, Void, Object[]>
implements ClientIF
{
Activity activity;
CallServiceTask(Activity activity) {
this.activity = activity;
}
public abstract void onResponseReceived(Object result);
protected Object[] doInBackground(Object... params)
{
HttpUriRequest req = (HttpUriRequest) params[0];
String url = (String) params[1];
return executeRequest(req, url);
}
protected onPostExecute(Object result) {
onResponseReceived(result);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,costructor已更改,因此您可以从每个Activity类调用.然后在RestClient中创建此类的实例
public class RestClient
{
CallServiceTask service = new CallServiceTask() {
@Override
public void onResponseReceived(Object result) {
// TODO Auto-generated method stub
}
};
}
Run Code Online (Sandbox Code Playgroud)
您可以使用get()检索您value/object的背部AsyncTask.
new CallServiceTask().execute(parameters).get();
Run Code Online (Sandbox Code Playgroud)
这将返回您返回的computed结果.但这将阻止您的UI,直到您的后台进程完成.
另一种选择是创建一个Interface或BroadcastReceiver,您可以在doInBackground()完成后立即返回值.我使用Interface和BroadcastReceiver创建了一个相同的演示,你可以从我的github检查
此外,通过使用第二种方法,您的UI将不会被阻止!
| 归档时间: |
|
| 查看次数: |
43839 次 |
| 最近记录: |