通过(From)AsyncTask

时间:2016-09-17 18:04:53

标签: android android-intent android-activity android-asynctask android-context

我在Stack Overflow上查了几个问题,向我的MainActivity发送 int 并将其显示在我的 TextView 上。但尝试初始化活动或上下文不起作用.. 我得到的最新错误是:

  

致命异常:AsyncTask#1                                                                                  处理:com.dahlstore.jsonparsingdemo,PID:32123                                                                                  java.lang.RuntimeException:执行时发生错误   doInBackground()                                                                                      在android.os.AsyncTask $ 3.done(AsyncTask.java:309)                                                                                      在   java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)                                                                                      at java.util.concurrent.FutureTask.setException(FutureTask.java:223)                                                                                      在java.util.concurrent.FutureTask.run(FutureTask.java:242)                                                                                      在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:234)                                                                                      在   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)                                                                                      在   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:588)                                                                                      在java.lang.Thread.run(Thread.java:818)                                                                                   引起:java.lang.NullPointerException:尝试调用虚拟   方法'android.content.Context   null对象上的android.app.Activity.getApplicationContext()'   参考                                                                                      在   com.dahlstore.jsonparsingdemo.JSONTask.doInBackground(JSONTask.java:63)                                                                                      在   com.dahlstore.jsonparsingdemo.JSONTask.doInBackground(JSONTask.java:21)                                                                                      在android.os.AsyncTask $ 2.call(AsyncTask.java:295)                                                                                      在java.util.concurrent.FutureTask.run(FutureTask.java:237)                                                                                      在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:234)                                                                                      在   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)                                                                                      在   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:588)                                                                                      在java.lang.Thread.run(Thread.java:818)09-17 18:31:37.015   32123-32152 / com.dahlstore.jsonparsingdemo E / Surface:   getSlotFromBufferLocked:未知缓冲区:0xabea80a0

有人可以解释为什么即使我使用Activity也无法发送我的意图。

/*ROW21*/      public class JSONTask extends AsyncTask<String,String, String>{

    OnDataSendToActivity dataSendToActivity;
    Activity activity;
    Intent intent;

    public JSONTask(MainActivity mainActivity) {
        dataSendToActivity = (OnDataSendToActivity)mainActivity;
    }

    public JSONTask(Activity activity){
        this.activity = activity;
    }

    @Override
    protected String doInBackground(String... params) {

        HttpURLConnection connection = null;
        BufferedReader reader = null;

        try {
            URL url = new URL(params[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();

            InputStream stream = connection.getInputStream();

            reader = new BufferedReader(new InputStreamReader(stream));
            StringBuffer buffer = new StringBuffer();

            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            JSONObject parentObject = new JSONObject(buffer.toString());
            JSONObject query = parentObject.getJSONObject("query").optJSONObject("results").optJSONObject("channel").optJSONObject("item");
            String temperature = query.getJSONObject("condition").optString("temp");
            String text = query.getJSONObject("condition").optString("text");

            int code = query.getJSONObject("condition").optInt("code");
           **//ROW 63**  intent = new Intent(activity.getApplicationContext(),MainActivity.class); 

            intent.putExtra("code",code);

            return temperature + " °C " +" and "+ text;

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        activity.startActivity(intent);
        dataSendToActivity.sendData(result);
    }

}

MainActivity

public class MainActivity extends AppCompatActivity implements OnDataSendToActivity{

    public TextView temperatureTextView,textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        temperatureTextView = (TextView) findViewById(R.id.temperatureTextView);
        textView = (TextView) findViewById(R.id.textView);

        new JSONTask(this).execute("https://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20woeid%3D906057%20and%20u%3D%27c%27&format=json");

        Intent intent = getIntent();
        if(intent!= null) {
            int code = getIntent().getIntExtra("code", 0);
            String codeToString = String.valueOf(code);
            textView.setText(codeToString);
        } else {
            Toast.makeText(MainActivity.this, "Intent is null", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void sendData(String str) {
        temperatureTextView.setText(str);
    }
}

更新的JSONTASK.JAVA

public class JSONTask extends AsyncTask<String,String, String>{
    OnDataSendToActivity dataSendToActivity;
    Context context;

    // single constructor to initialize both the context and dataSendToActivity
    public JSONTask(Context context){
        this.context = context;
        dataSendToActivity = (OnDataSendToActivity) ((Activity) context);
    }

    @Override
    protected String doInBackground(String... params) {
        HttpURLConnection connection = null;
        BufferedReader reader = null;
        StringBuffer buffer = new StringBuffer();

        try {
            URL url = new URL(params[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            InputStream stream = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(stream));
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return buffer.toString();
    }

    @Override
    protected void onPostExecute(String result) {
        try {
            JSONObject parentObject = new JSONObject(result);
            JSONObject query = parentObject.getJSONObject("query").optJSONObject("results").optJSONObject("channel").optJSONObject("item");
            String temperature = query.getJSONObject("condition").optString("temp");
            String text = query.getJSONObject("condition").optString("text");
            int code = query.getJSONObject("condition").optInt("code");
            temperature += " °C " +" and "+ text;

            Intent intent = new Intent(context, MainActivity.class);
            intent.putExtra("code", code);
            context.startActivity(intent);
            if(dataSendToActivity != null){
                dataSendToActivity.sendData(temperature);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

更新的主要活动

public class MainActivity extends AppCompatActivity implements OnDataSendToActivity{

    public TextView temperatureTextView,textView;
    Intent intent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        temperatureTextView = (TextView) findViewById(R.id.temperatureTextView);
        textView = (TextView) findViewById(R.id.textView);
        intent = getIntent();
        new JSONTask(this).execute("https://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20woeid%3D906057%20and%20u%3D%27c%27&format=json");

    }


    @Override
    public void sendData(String str) {
        temperatureTextView.setText(str);
    }
}

3 个答案:

答案 0 :(得分:1)

您收到错误是因为activity为空。这是因为你有两个构造函数。

// this is the constructor that is called
public JSONTask(MainActivity mainActivity) {
    dataSendToActivity = (OnDataSendToActivity)mainActivity;
}

// this is not called
public JSONTask(Activity activity){
    this.activity = activity;
}

因此,您的activity变量永远不会被初始化。

查看我的更改,

public class JSONTask extends AsyncTask<String,String, String>{
    OnDataSendToActivity dataSendToActivity;
    Context context;

    // single constructor to initialize both the context and dataSendToActivity
    public JSONTask(Context context){
        this.context = context;
        dataSendToActivity = (OnDataSendToActivity) ((Activity) context);
    }

    @Override
    protected String doInBackground(String... params) {
        HttpURLConnection connection = null;
        BufferedReader reader = null;
        StringBuffer buffer = new StringBuffer();

        try {
            URL url = new URL(params[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            InputStream stream = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(stream));
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return buffer.toString();
    }

    @Override
    protected void onPostExecute(String result) {
        try {
            JSONObject parentObject = new JSONObject(result);
            JSONObject query = parentObject.getJSONObject("query").optJSONObject("results").optJSONObject("channel").optJSONObject("item");
            String temperature = query.getJSONObject("condition").optString("temp");
            String text = query.getJSONObject("condition").optString("text");
            int code = query.getJSONObject("condition").optInt("code");
            temperature += " °C " +" and "+ text;

            if(dataSendToActivity != null){
                dataSendToActivity.sendData(temperature, code);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

MainActivity

public class MainActivity extends AppCompatActivity implements OnDataSendToActivity {

    public TextView temperatureTextView,textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        temperatureTextView = (TextView) findViewById(R.id.temperatureTextView);
        textView = (TextView) findViewById(R.id.textView);

        new JSONTask(this).execute("https://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20woeid%3D906057%20and%20u%3D%27c%27&format=json");
    }

    @Override
    public void sendData(String str, String code) {
        temperatureTextView.setText(str);
        textView.setText(code);
    }
}

您的OnDataSendToActivity界面将成为

public interface OnDataSendToActivity {
    void sendData(String str, String code);
}

答案 1 :(得分:0)

我认为错误是你在Async中使用了getIntExtra。而不是使用putIntExtra将变量保存在intent中。

Put用于存储值,getIntent函数用于从intent获取数据。

使用此行,

intent = new Intent(getApplicationContext(),MainActivity.class); 

intent = new Intent(YourClassName.class,MainActivity.class); 

答案 2 :(得分:0)

您实际上不必使用意图将“代码”发送到活动。在你的doInBackground中,将你的“代码”放入一个字符串变量(你需要正确地解析它),然后将该字符串作为参数放回你的返回。

然后在postExecute(String result)中,变量result应该是从doInBackground返回的值。 dataSendToActivity.sendData(result)现在应该可以正常工作。