【发布时间】:2015-01-25 03:07:14
【问题描述】:
以下场景的最佳策略是什么:
我的应用程序将定期向服务器运行 PHP 脚本发送和接收 http 请求。 我尝试了由 AlarmManager 触发的服务或直接单击其小部件。设备上的直接操作工作正常(如随机数,请参阅http://www.vogella.com/tutorials/AndroidWidgets/article.html) 当涉及到请求时,这些应该在异步任务中完成。我试图从异步任务的 postexecute 部分更新小部件(remoteView),但它不起作用。
谁能给我一些提示或者sn-ps?
提前谢谢你
更新:
具有异步任务的小部件提供程序类:
public class MyWidgetProvider extends AppWidgetProvider {
private static final String ACTION_CLICK = "ACTION_CLICK";
long ddd;
String dddd;
RemoteViews remoteViews;
TextView tvUpdate;
private static final String LOG = "de.vogella.android.widget.example";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Log.w(LOG, "onUpdate method called");
// Get all ids
ComponentName thisWidget = new ComponentName(context,
MyWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
// Build the intent to call the service
Intent intent = new Intent(context.getApplicationContext(),
UpdateWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
// Update the widgets via the service
context.startService(intent);
}
}
具有异步任务的服务类对网站进行 ping 操作(仅用于测试目的,以后的请求将在那里完成) 目的是在小部件中显示 ping:
public class UpdateWidgetService extends Service {
private static final String LOG = "de.vogella.android.widget.example";
long ddd;
String dddd;
RemoteViews remoteViews;
TextView tvUpdate;
@Override
public void onStart(Intent intent, int startId) {
Log.i(LOG, "Called");
// create some random data
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
.getApplicationContext());
int[] allWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
ComponentName thisWidget = new ComponentName(getApplicationContext(),
MyWidgetProvider.class);
int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
Log.w(LOG, "From Intent" + String.valueOf(allWidgetIds.length));
Log.w(LOG, "Direct" + String.valueOf(allWidgetIds2.length));
for (int widgetId : allWidgetIds) {
// create some random data
int number = (new Random().nextInt(100));
remoteViews = new RemoteViews(this
.getApplicationContext().getPackageName(),
R.layout.widget_layout);
Log.w("WidgetExample", String.valueOf(number));
if (dddd!=null)Log.w("dddd -", dddd);
new LongOperation().execute("");
if (dddd!=null)Log.w("dddd +", dddd);
// Set the text
remoteViews.setTextViewText(R.id.update,
"Random: " + String.valueOf(number));
// Register an onClickListener
Intent clickIntent = new Intent(this.getApplicationContext(),
MyWidgetProvider.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
allWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), 0, clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.add(Calendar.SECOND, 5);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), 5 * 1000, pendingIntent);
}
stopSelf();
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
ddd = MainActivity.isURLReachable();
Log.e("ddd", ddd + "");
dddd = ddd + " ms";
Log.e("dddd", dddd);
return null;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.e("POST dddd", dddd);
remoteViews.setTextViewText(R.id.update, dddd);
}
}
}
问题是无法从执行后的异步任务访问小部件。
更新 2:
如何从 postexecute 方法中获取 WidgetID?
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(UpdateWidgetService.this
.getApplicationContext());
int[] allWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
ComponentName thisWidget = new ComponentName(getApplicationContext(),
MyWidgetProvider.class);
int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
Log.w(LOG, "From Intent" + String.valueOf(allWidgetIds.length));
Log.w(LOG, "Direct" + String.valueOf(allWidgetIds2.length));
for (int widgetId : allWidgetIds) {
// create some random data
int number = (new Random().nextInt(100));
remoteViews = new RemoteViews(UpdateWidgetService.this
.getApplicationContext().getPackageName(),
R.layout.widget_layout);
Log.w("WidgetExample", String.valueOf(number));
if (dddd!=null)Log.w("dddd -", dddd);
new LongOperation().execute("");
if (dddd!=null)Log.w("dddd +", dddd);
// Set the text
remoteViews.setTextViewText(R.id.update,
"Random: " + dddd);
// Register an onClickListener
Intent clickIntent = new Intent(UpdateWidgetService.this.getApplicationContext(),
MyWidgetProvider.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
allWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), 0, clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
【问题讨论】:
-
“它不起作用”——请完整准确地解释您的症状是什么。 “不工作”不是对您的症状非常有用的描述。除此之外,如果您不给我们“不工作”的代码来查看您的“不工作”代码,我们将无法帮助您。最后,服务不应该使用
AsyncTask——也许你的服务应该是IntentService。 -
谢谢你是对的,我提供了一些关于结构的细节。
标签: android android-widget android-service