Je vais garder celui-ci aussi simple que possible.
J'ai une méthode dans ma couche de contrôle qui utilise une classe CallServiceTask
qui étend AsyncTask
. Lorsque vous appelez new CallServiceTask().execute(parameters)
Comment récupérer les données renvoyées de doInBackground
? Tous les tutoriels que j'ai trouvés utilisent la classe qui étend AsyncTask
directement à partir de leur Activity
.
Mon problème est un peu plus complexe que cela.
Tout ce que je veux, c'est prendre le Object[]
renvoyé par doInBackground
et le définir sur les données privées membres de ma classe RestClient
.
CallServiceTask
ressemble à ceci:
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);
}
}
Et ma classe RestClient ressemble à ceci:
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();
}
}
La seule façon de faire est d'utiliser un rappel. Vous pouvez faire quelque chose comme ça:
new CallServiceTask(this).execute(request, url);
Ensuite, dans votre CallServiceTask, ajoutez une variable de classe locale et appelez une méthode de cette classe dans votre 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);
}
}
Ensuite, utilisez simplement l’objet comme vous le souhaitez dans la méthode onBackgroundTaskCompleted()
de votre classe RestClient.
Une solution plus élégante et extensible serait d'utiliser des interfaces. Pour un exemple d'implémentation, voir this library. Je viens juste de commencer mais il contient un exemple de ce que vous voulez.
comme @ saad-farooq l'a mentionné, vous pouvez utiliser interface pour cela. Vous pouvez donc utiliser le Handler.Callback ou définir le vôtre:
public interface ClientIF {
public void onResponseReceived(Object result);
}
alors vous devez l'implémenter dans votre 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);
}
}
notez que le costructeur est modifié afin que vous puissiez appeler à partir de chaque classe Activity . Créez ensuite l'instance de cette classe dans votre RestClient
public class RestClient
{
CallServiceTask service = new CallServiceTask() {
@Override
public void onResponseReceived(Object result) {
// TODO Auto-generated method stub
}
};
}
Vous pouvez utiliser get()
pour récupérer votre value/object
depuis AsyncTask
.
new CallServiceTask().execute(parameters).get();
Cela vous retournera computed
résultat que vous revenez. Mais cela bloquera votre interface utilisateur jusqu'à ce que votre processus d'arrière-plan soit terminé.
Une autre option consiste à créer une interface ou un BroadcastReceiver auquel vous renverrez la valeur dès que votre doInBackground()
est terminé. J'avais créé une démo pour le même en utilisant Interface et BroadcastReceiver, vous pouvez vérifier si depuis mon github
De plus, en utilisant la deuxième approche, votre interface utilisateur ne sera pas bloquée!
public class getOperators extends AsyncTask<Void, Void, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
items = new ArrayList();
dialog = new ProgressDialog(PrepaidOperatorsListActivity.this);
dialog.setMessage("Please Wait...");
dialog.setCancelable(false);
dialog.show();
}
@Override
protected String doInBackground(Void... params) {
BufferedReader reader;
StringBuffer buffer;
String res = null;
try {
URL url = new URL("");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(40000);
con.setConnectTimeout(40000);
con.setRequestMethod("GET");
con.setRequestProperty("Content-Type", "application/json");
int status = con.getResponseCode();
InputStream inputStream;
if (status == HttpURLConnection.HTTP_OK) {
inputStream = con.getInputStream();
} else {
inputStream = con.getErrorStream();
}
reader = new BufferedReader(new InputStreamReader(inputStream));
buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
res = buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return res;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
System.out.println("JSON RESP:" + s);
String response = s;
try {
JSONObject ecomerrce = new JSONObject(response);
JSONArray jsonArray = ecomerrce.getJSONArray("prepaid_operators");
for (int j = 0; j < jsonArray.length(); j++) {
JSONObject jsonObject = jsonArray.getJSONObject(j);
PrepaidOperatorsPojo prepaidOperatorsPojo = new PrepaidOperatorsPojo(jsonObject.getString("operator_name"), jsonObject.getString("operator_code"), jsonObject.getString("operator_display_comission"), jsonObject.getString("operator_calculate_comission"));
items.add(prepaidOperatorsPojo);
}
if (items.size() > 0) {
dialog.dismiss();
prepaidOperatorListAdapter = new PrepaidOperatorListAdapter(PrepaidOperatorsListActivity.this, items);
rvPrepaidOperatorList.setAdapter(prepaidOperatorListAdapter);
} else {
dialog.dismiss();
Toast.makeText(PrepaidOperatorsListActivity.this, "No Data to display", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private void walletStatements() {
JSONObject post_search = new JSONObject();
try {
post_search.put("username", getUserName);
} catch (JSONException e) {
e.printStackTrace();
}
if (post_search.length() > 0) {
try {
new Getwalletstatements().execute(String.valueOf(post_search));
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Getwalletstatements extends AsyncTask<String, String, String> {
String JsonResponse = null;
ProgressDialog dialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(ReportsActivity.this);
dialog.setMessage("Please Wait...");
dialog.setCancelable(false);
dialog.show();
}
@Override
protected String doInBackground(String... params) {
String JsonDATA = params[0];
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
URL url = null;
try {
url = new URL(Constant.url+"GetReports_v9.php");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true); // is output buffer writter
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");//set headers and method
Writer writer = new BufferedWriter(new OutputStreamWriter(urlConnection.getOutputStream(), "UTF-8"));
writer.write(JsonDATA);// json data
writer.close();
InputStream inputStream = urlConnection.getInputStream();//input stream
StringBuffer buffer = new StringBuffer();
if (inputStream == null) { // Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String inputLine;
while ((inputLine = reader.readLine()) != null)
buffer.append(inputLine + "\n");
if (buffer.length() == 0) { // Stream was empty. No point in parsing.
return null;
}
JsonResponse = buffer.toString();
return JsonResponse;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
}
}
}
return null;
}
@Override
protected void onPostExecute(String s) {
if (JsonResponse != null) {
try {
NetworkIN.iv= Constant.iv;
NetworkIN.change=Constant.key;
NetworkIN mCrypt=new NetworkIN();
String decrypted = new String( mCrypt.decrypt(JsonResponse.trim()) );
if(decrypted!=null){
JSONObject ordersHistory = new JSONObject(decrypted);
msg = ordersHistory.getString("msg");
JSONArray jsonArray = ordersHistory.getJSONArray("PPDetails");
ordersCount = jsonArray.length();
//for (int j = 0; j < jsonArray.length(); j++)
for (int j = jsonArray.length() - 1; j >= 0; j--)
{
JSONObject jsonObject = jsonArray.getJSONObject(j);
String message,total_in,inType ;
total_in =jsonObject.getString("total_in");
inType =jsonObject.getString("in_type");
message="Congratulations your wallet is credited by Rs."+total_in+" because of "+inType;
ReportsPojo reportsPojo = new ReportsPojo(jsonObject.getString("reg_id"),
jsonObject.getString("username"),
jsonObject.getString("transfer_from"),
jsonObject.getString("transfer_to"),
jsonObject.getString("total_in"),
jsonObject.getString("tds"),
jsonObject.getString("in_amount") ,
jsonObject.getString("out_amount"),
jsonObject.getString("in_type"),
jsonObject.getString("created_on"),
message);
reportsItems.add(reportsPojo);
}
}else{
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
if (msg.equals("Success")) {
reportsAdapter = new ReportsAdapter(ReportsActivity.this, reportsItems);
reportsListview.setAdapter(reportsAdapter);
} else {
Toast.makeText(ReportsActivity.this, "Sorry "+msg, Toast.LENGTH_LONG).show();
}
dialog.dismiss();
} else {
dialog.dismiss();
}
}
public class MyAsyncTask extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
//showProgressDialog
dialog = new ProgressDialog(this);
dialog.setMessage("Loading........");
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.show();
}
@Override
protected String doInBackground(String... strings) {
HttpURLConnection httpURLConnection;
BufferedReader reader;
int responseCode ;
try {
URL url = new URL(YOUR_URL);
URLConnection urlConnection = url.openConnection();
httpURLConnection = (HttpURLConnection) urlConnection;
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setDoOutput(true);
responseCode = httpURLConnection.getResponseCode();
InputStream inputStream = httpURLConnection.getInputStream();
if (inputStream != null) {
if (responseCode == 200) {
reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder buffer = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
return buffer.toString();
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
progressDialog.dismiss();
// Fetch Your Data Add Your Code Here
}
}