我正在尝试为Oreo及其以上版本创建一个简单的小部件,以便在定期点击时重新加载其数据。以下是我的大纲代码:
public class WodWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
updateWodWidget(context);
}
static void updateWodWidget(Context context) {
context.startForegroundService(new Intent(context, UpdateService.class));
}
public static class UpdateService extends IntentService {
private static final String TAG = "WodWidgetUpdateService";
private final Handler mHandler = new Handler();
public UpdateService() { super(TAG); }
@Override
public IBinder onBind(Intent intent) { return null; }
@Override
public void onCreate() {
super.onCreate();
String channelId = "foobar";
String channelName = "Widget update service";
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.createNotificationChannel(channel);
Notification notification = new Notification.Builder(getApplicationContext())
.setChannelId(channelId)
.setContentTitle("notification title")
.setContentText("notification content")
.build();
startForeground(1, notification);
}
@Override
protected void onHandleIntent(Intent intent) {
if (Clicks.ACTION_CLICK.equals(intent.getAction())) {
Clicks.handleClickAction(this, mHandler);
} else {
getWodData(this);
}
}
protected void getWodData(final Context context) {
WodData.getInstance().invalidate();
WodWidget.updateViews(context);
GetHTMLTask task = new GetHTMLTask(new GetHTMLTask.OnTaskCompleted() {
@Override
public void onTaskCompleted() {
WodWidget.updateViews(context);
}
});
task.execute(WodData.PARSE_URL);
}
}
static void singleClickHandler(Context context) {
updateWodWidget(context);
}
static void doubleClickHandler(Context context) { [...] }
private static void updateViews(Context context) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.wod_widget);
WodData wd = WodData.getInstance();
view s.setTextViewText(R.id.appwidget_text, "foobar");
Intent intent = new Intent(Clicks.ACTION_CLICK, null, context, UpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.layoutWidget, pendingIntent);
ComponentName thisWidget = new ComponentName(context, WodWidget.class);
AppWidgetManager.getInstance(context).updateAppWidget(thisWidget, views);
}
}
现在这个构建并运行良好,有一段时间,也可以单击小部件。但是过了一会儿(几分钟左右),点击不再刷新小部件了,我在logcat中看到以下条目:
W/ActivityManager: Background start not allowed: service Intent { act=com.mywidget.action.CLICK flg=0x10000000 cmp=com.mywidget/.WodWidget$UpdateService bnds=[56,367][620,1111] } to com.mywidget/.WodWidget$UpdateService from pid=-1 uid=10083 pkg=com.mywidget
所以我猜它正在成为后台服务而不是前台服务,但为什么以及如何防止这种情况发生呢?