通过(From)AsyncTask 向 MainActivity 发送意图
Posted
技术标签:
【中文标题】通过(From)AsyncTask 向 MainActivity 发送意图【英文标题】:Sending intent to MainActivity through (From) AsyncTask 【发布时间】:2017-01-25 18:44:37 【问题描述】:我在 Stack Overflow 上查找了几个问题,用于向我的 MainActivity 发送 int 并将其显示在我的 TextView 上。但是尝试初始化活动或上下文不起作用.. 我得到的最新错误是:
致命异常:AsyncTask #1 进程:com.dahlstore.jsonparsingdemo,PID:32123 java.lang.RuntimeException:执行时发生错误 做背景() 在 android.os.AsyncTask$3.done(AsyncTask.java:309) 在 java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) 在 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 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();
更新的 MAINACTIVITY
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);
【问题讨论】:
共享所有错误日志。 Aghazadeh 先生,我已经分享过了。 将断点添加到`dataSendToActivity = (OnDataSendToActivity)mainActivity;`,`dataSendToActivity = (OnDataSendToActivity)mainActivity;` 并检查。 原因:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法 'android.content.Context android.app.Activity.getApplicationContext()' 先生。 Aghazadeh,当不使用 Intent 时,onPostExecute 将结果发送到我的 MainActivity 没有任何问题。只有当我添加 Intent 函数来检索我的“int 代码”时,才会发生错误 【参考方案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);
【讨论】:
非常感谢 K Neeraj Lal 先生。不幸的是,我仍然遇到两个错误。第一个是我不能再在我的 postExecute 方法中返回“温度 +”°C“+”和“+文本”,因为它是 void。将它从 void 更改为 String 会给我“不兼容的返回类型”。第二个错误:activity inside of: Intent intent = new Intent(activity, MainActivity.class);使用上面的代码时无法解析为符号。我想添加 public JSONTask(Activity activity) this.activity = activity; 在我的代码中? 我的错。见编辑。没有使用 IDE 编写代码。 不,您不必添加该构造函数。 是的,按照您当前的架构,这是预期的。只需要一些小的调整。查看编辑。 非常感谢您的帮助!我真的很感激,现在一切都很好!【参考方案2】:您实际上不必使用意图将您的“代码”发送到活动。在您的 doInBackground 中,将您的“代码”放入一个字符串变量中(您需要正确解析它),然后将该字符串作为返回值的参数。
然后在 postExecute(String result) 中,变量 result 应该是你从 doInBackground 返回的值。 dataSendToActivity.sendData(result) 现在应该可以正常工作了。
【讨论】:
这是一个非常好的主意。我知道并已通过我的 postExecute 方法成功发送了“代码”。问题是我的 MainActivity 中的一个函数应该用作索引,因此我可以从我的可绘制文件夹中获取正确的图像。我无法使用 dataSendToActivity 返回我的“代码”值。如您所见,那是因为我现在要返回两个字符串(温度和文本)。意图 i= getIntent(); int value= i.getIntExtra("intVariableName", 0);可绘制的 weatherIconDrawable = getResources().getDrawable(value); weatherIconImageView.setImageDrawable(weatherIconDrawable); 我明白了。你可以完全删除意图。然后将“代码”值附加到 doInBackground 中的返回字符串。在 postExecute 中,您可以解析值,以便代码转到 textView 而温度转到 temperatureTextView。 您需要检查 Neeraj 评论,您的活动参考需要修复。【参考方案3】:我认为错误是您在异步中使用 getIntExtra。而不是使用 putIntExtra 将变量保存在意图中。
Put 用于存储值,getIntent 函数用于从 Intent 中获取数据。
使用这条线,
intent = new Intent(getApplicationContext(),MainActivity.class);
或
intent = new Intent(YourClassName.class,MainActivity.class);
【讨论】:
我没有 putIntExtra 作为替代方案。但是我只是改为 putExtra 而不是 getIntExtra 并更新了错误消息。 @user3506 我在答案中编辑了一行。试试看。 不幸的是,这两个都不起作用。但感谢您的努力! @user3506 编辑后您仍然在此行收到 NulPointerError? 不,Puri 先生,我使用了@K Neeraj Lal 的建议,效果很好。我只需要找出为什么我的应用程序会一遍又一遍地重新启动......你看到问题了吗? (大约五分钟前更新代码)以上是关于通过(From)AsyncTask 向 MainActivity 发送意图的主要内容,如果未能解决你的问题,请参考以下文章
通过 AsyncTask 下载图像并将其显示在 Imageview 中而不存储在 sdcard 中