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

时间:2013-12-30 08:53:24

标签: java android android-asynctask android-internet

这是我的代码:

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;
        }

    }
}

由于getPrediction(),此代码始终在NulPointerException中崩溃。 NullPointerException是因为Async任务需要时间来生成String,getPrediction()方法在准备好之前返回字符串。所有这些方法都是通过外部类调用的,所以我该如何解决这个问题?

5 个答案:

答案 0 :(得分:0)

你可以检查ASYNCTASK是否已经完成执行,直到那时你可以停止从方法getPrediction();

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

答案 1 :(得分:0)

尝试将String方法中的doInBackground作为:

返回
  return jsonString;

答案 2 :(得分:0)

正如你指出的那样

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

您应该在doInBackground中的线程中运行基于网络的操作,然后加入该线程。然后,您应该致电getPrediction() in onPostExecute()。因此,在调用方法之前,您将获得数据。

答案 3 :(得分:0)

请改用onPostExecute()onPostExecute()完成后会收到doInBackground()的返回值。从那里你可以做任何你需要做的事情。

如果onPostExecute()对您来说不够灵活,请考虑使用CountDownLatch来停止主代码执行,直到AsyncTask返回。

答案 4 :(得分:0)

以下是您可以实施的示例代码

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);
    }

}