简体   繁体   English

Android在“ AsyncTask”之后返回一个字符串

[英]Android is returning a String after 'AsyncTask'

Here is my code: 这是我的代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import android.os.AsyncTask;
import android.util.Log;

public class JsonController 
{
    private JSONObject inputData, json, finalResult;
    private String authentication;

    public JsonController()
    {
        json = new JSONObject();

        inputData = new JSONObject();
    }

    public void createAuthentication(String userName, String apiKey)
    {
        authentication = "";
    }


    public void setModel(String model) throws JSONException
    {
        json.put("model",model);
    }

    public void setData(String id, String deviceType) throws JSONException
    {
        inputData.put(id, deviceType);
    }



    public void getPrediction()
    {
        new sendJSon().execute("");
            return finalResult.toString();
    }




    private class sendJSon extends AsyncTask<String,Void,String>
    {

        @Override
        protected String doInBackground(String... params) {
            // TODO Auto-generated method stub
            HttpClient httpclient = new DefaultHttpClient();

            HttpPost httppost = new HttpPost(authentication);
            httppost.setHeader("Content-type", "application/json; charset=utf-8");

            try {
                  // Add your data
                  json.put("input_data", inputData);

                  StringEntity se = new StringEntity( json.toString());
                  httppost.setEntity(se); 

                  // Execute HTTP Post Request
                  HttpResponse response = httpclient.execute(httppost);

                  BufferedReader reader = new BufferedReader(
                          new InputStreamReader(
                                  response.getEntity().getContent(), "UTF-8"));
                  String jsonString = reader.readLine();
                  JSONTokener tokener = new JSONTokener(jsonString);

                  finalResult = new JSONObject(tokener);
              }
              catch(Exception e)
              {
                  Log.d("Error here", "Error is here",e);
              }


            return null;
        }

    }
}

This code always crashes in getPrediction() because of NulPointerException . 由于NulPointerException此代码始终在getPrediction()NulPointerException NullPointerException is because the Async task take time to generate the String, and the getPrediction() method returns the string before it is ready. NullPointerException是因为Async任务花费时间来生成String,并且getPrediction()方法在准备就绪之前返回了该字符串。 All of these methods get called via external classes, so how can I solve this? 所有这些方法都是通过外部类调用的,那么我该如何解决呢?

you can check whether ASYNCTASK has finished execution or not until then you can halt the returning of string from method getPrediction(); 您可以检查ASYNCTASK是否已完成执行,直到您可以停止从方法getPrediction();返回字符串getPrediction();

if(CLASSOBJECT!= null && CLASSOBJECT.getStatus() == Status.RUNNING) {
            //DO NOT RETURN ANY VALUE
        }else{
//RETURN VALUE
}

尝试在doInBackground方法中返回String

  return jsonString;

As you have pointed 正如你所指出的

outNullPointerException is because the Async task take time to generate the
String, and the getPrediction() method returns the string before it is ready.

You should run your network based operation in thread in doInBackground and then join that thread. 您应该在doInBackground中的线程中运行基于网络的操作,然后加入该线程。 Then you should call getPrediction() in onPostExecute() . 然后,你应该叫getPrediction() in onPostExecute() Thus you'll have the data before the method is called. 这样,在调用该方法之前,您将拥有数据。

Use onPostExecute() instead. 改用onPostExecute() onPostExecute() receives the return value from doInBackground() after it finishes. onPostExecute()接收从返回值doInBackground()为完成后。 From there you can do whatever needs to be done with your result. 从那里,您可以完成需要做的任何事情。

If onPostExecute() isn't flexible enough for you, consider using a CountDownLatch to stall your main code execution until AsyncTask returns. 如果onPostExecute()不够灵活,请考虑使用CountDownLatch暂停主代码执行,直到AsyncTask返回。

Here is an sample code which you can implement 这是您可以实现的示例代码

public interface AsyncResponseHandler {
    public String resultCall(String resultStr);
}

public class MyMainClass extends Activity implements AsyncResponseHandler{

    public void doProcessing(){
        new AsynTasker(this).execute(null); //here this is instance of AsyncResponseHandler
    }

    @Override
    public String resultCall(String resultStr) {
        //here you will receive results from your async task after execution and you can carry out whatever process you want to do.
    }
}

public class AsynTasker extends AsyncTask<String,Void,String>{
    AsyncResponseHandler handler=null;
    public AsynTasker(AsyncResponseHandler handler){
      this.handler = handler
    }

    @Override
    protected String doInBackground(String... params) {
         // do your processing
         return resultString;
    }

    @Override
    protected void onPostExecute(String result) {
        this.handler.resultCall(result);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM