【发布时间】:2015-01-18 15:41:02
【问题描述】:
我一直在尝试一整天,但我似乎无法弄清楚。我正在尝试从 BroadcastReceiver 中的 AsyncTask 返回一个字符串,但我不确定如何正确执行(Java 中的新功能)。我有一个应用程序可以访问互联网并读取一个文本文件,这个文本文件是一个长字符串。我将字符串分隔成一个数组并以这种方式使用它的内容。在 BroadcastReceiver 中,我想根据用户在通知栏上的设置每 10-60 分钟广播一次(更新)气象站的温度。
我应该使用线程而不是 AsyncTask 吗?
我得到的错误是以下行:
字符串输出 = new GetWeatherValues().execute(weburi);
我还尝试了以下被注释掉的代码:
// GetWeatherValues clientraw = new GetWeatherValues();
// clientraw.doInBackground(weburi);
下面是我的班级,请帮忙,我搜索了很多,仍然没有结果。
public class UpdateFrequency extends BroadcastReceiver {
// Notification Text Elements
private final CharSequence tickerText = "Weather Updated";
private CharSequence contentTitle = "Weather at ";
private final CharSequence contentText = "Current Temperature is ";
final String http = "http://";
final String clientraw = "/clientraw.txt";
String weburi, webUrl;
// Notification Action Elements
private Intent notificationIntent;
private PendingIntent mContentIntent;
// Notification ID to allow for future updates
private static final int MY_NOTIFICATION_ID = 1;
final String PREFS_NAME = "SettingsFile";
SharedPreferences settings;
public String[] parts;
public static final String WebAddress = "webAddressKey";
@SuppressLint("NewApi")
@Override
public void onReceive(Context context, Intent intent) {
Log.e("log_etag", "Entered Update Frequency");
settings = context.getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);
if (settings.contains(WebAddress)) {
webUrl = settings.getString(WebAddress, "");
weburi = http + webUrl + clientraw;
Log.e("log_etag", "WEB URL Frequency " + weburi);
}
// GetWeatherValues clientraw = new GetWeatherValues();
// clientraw.doInBackground(weburi);
String output = new GetWeatherValues().execute(weburi);
String[] parts = output.split(" ");
ArrayList<String> clientRawData = new ArrayList<String>();
clientRawData.addAll(Arrays.asList(parts));
//Time of last update from weather station.
contentTitle = contentTitle + parts[29] + ":" + parts[30];
Log.e("log_etag", "Content Title " + contentTitle);
// The Intent to be used when the user clicks on the Notification View
notificationIntent = new Intent(context, MainActivity.class);
// The PendingIntent that wraps the underlying Intent
mContentIntent = PendingIntent.getActivity(context, 0,
notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
// Build the Notification
Notification.Builder notificationBuilder = new Notification.Builder(
context).setTicker(tickerText)
.setSmallIcon(android.R.drawable.stat_sys_warning)
.setAutoCancel(true).setContentTitle(contentTitle)
.setContentText(contentText).setContentIntent(mContentIntent);
// Get the NotificationManager
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
// Pass the Notification to the NotificationManager:
mNotificationManager.notify(MY_NOTIFICATION_ID,
notificationBuilder.build());
}
private class GetWeatherValues extends AsyncTask<Void, Integer, String> {
@Override
protected String doInBackground(Void... params) {
try {
HttpClient httpclient = new DefaultHttpClient();
// get url data
HttpPost httppost = new HttpPost(weburi);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream webs = entity.getContent();
// convert response to string
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(webs, "iso-8859-1"),
8);
// read one line of code, file is one whole string.
try {
String returnData = reader.readLine();
webs.close();
return returnData;
} catch (Exception e) {
Log.e("log_tag",
"Error in displaying textview "
+ e.toString());
e.printStackTrace();
}
} catch (Exception e) {
Log.e("log_tag",
"Error converting string " + e.toString());
}
} catch (Exception e) {
Log.e("log_tag",
"Error in http connection " + e.toString());
}
return null;
}
}
}
【问题讨论】:
-
不要在广播接收器中运行异步任务。在
onReceive方法完成后,认为接收器实例不可用。使用接收器启动IntentService或Service,这将完成实际工作。 -
谷歌“EventBus”。您可以使用它将数据从服务发布到活动或任何东西之间。
-
运行线程怎么样?这也是个坏主意吗?
-
除非您需要上下文,否则应该没问题。但!
IntentService在后台线程上运行(因此您可以使用 HTTP)并为您提供上下文。而且由于您不会将结果发回给接收器(此时已结束),它非常适合。 -
AsyncTask在活动(或保留片段)中使用时可以。如果您需要将其解耦,您可以使用接收器-服务对并将结果发布给任何想要它的人(这里是在事件总线中)。或者该服务使用CursorLoader写入您在活动中观察到的内容提供者(同样,服务和活动之间没有直接连接)。我只是在折腾想法,请务必检查实际答案。
标签: java android android-asynctask