【问题标题】:Android is returning a String after 'AsyncTask'Android 在“AsyncTask”之后返回一个字符串
【发布时间】:2014-01-17 03:27:37
【问题描述】:

这是我的代码:

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

    }
}

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

【问题讨论】:

  • onPostExecute(),谷歌!在这里你会找到一个参考:developer.android.com/reference/android/os/AsyncTask.html
  • 哪一行得到NPE?发布logcat,您将从void 类型函数返回字符串..
  • 发布您的onPostExecute() 方法。 @FlowOverStack。
  • getPrediction 无效。它不能返回字符串

标签: java android android-asynctask android-internet


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    尝试在您的doInBackground 方法中将String 返回为:

      return jsonString;
    

    【讨论】:

      【解决方案3】:

      正如你所指出的

      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()。因此,您将在调用方法之前获得数据。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          这是您可以实现的示例代码

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-04-30
            • 2012-08-21
            • 2018-10-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多