gpt4 book ai didi

android - 来自 appWidget 的网络请求

转载 作者:行者123 更新时间:2023-11-29 00:51:36 40 4
gpt4 key购买 nike

SO 上有许多类似的问题,但它们都是 O 之前的问题,IntentService 在其中工作得很好。我试图将它作为 JobIntentService 来做,但延迟是 Not Acceptable 。我的小部件的网络交换应该非常快,或者根本不会,socketTimeout 设置为 100 毫秒,因此几秒钟的延迟令人沮丧。

我想在这里尝试几种解决方案。首先,从上下文中创建一个 foregroundService。据我所知,在服务被终止之前我有 5 秒的时间,所以如果我的交换只需要其中的一小部分,我应该很好。这个假设是否正确?这对 foregroundService 有用吗?

接下来,如果我只是通过在我的 AppWidgetProvider 的 onReceive 中手动启动一个新线程来实现呢?正如我所说,网络交换应该花费不到四分之一秒。在那段时间上下文可能会发生什么?

从 appWidget 发出快速网络请求的最佳方式是什么,应该在它发送广播后立即发生?

最佳答案

在回答这个问题时有几点需要指出。我们有 appWidgets 使用服务来处理事务,因为 jobService 不是我们的选择。分享我们所做的一些事情,希望对您有所帮助。

关于你的第一个问题:
该服务从 appWidget 提供程序调用并完成所有工作,并且它必须作为 Oreo+ 上的前台服务调用,如果该前台服务在调用后 5 秒内未启动,您将得到一个异常:“Context.startForegroundService did而不是调用 Service.startForeground”。 Google 跟踪器中有一个 Unresolved 问题,似乎还没有解决这个问题,所以你应该确保你也阅读了这篇文章。有些人建议将以下代码放在服务的 onCreate() 和 onStart() 中。问题是 https://issuetracker.google.com/issues/76112072 .

我建议在从提供商调用服务后,在服务中完成您需要的所有工作。 (还记得为 Oreo+ 使用通知 channel )例如:

在 appWidget 提供者 onUpdate() 中:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(serviceIntent));
} else {
context.startService(new Intent(serviceIntent));
}

然后在您的服务类中 - 根据我在上面发布的问题链接将其放入 onStartCommand() 和 onCreate()。

savedIntent = intent;
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

//Google Issue tracker https://issuetracker.google.com/issues/76112072 as of 9/26/2018. StartForeground notification must be in both onCreate and onStartCommand to minimize
//crashes in event service was already started and not yet stopped, in which case onCreate is not called again
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(PRIMARY_NOTIF_CHANNEL, "YOUR NOTIFICATION CHANNEL", NotificationManager.IMPORTANCE_DEFAULT);
channel.setSound(null, null);
channel.enableVibration(false);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}

Notification notification = new NotificationCompat.Builder(this, PRIMARY_NOTIF_CHANNEL)
.setSmallIcon(R.drawable.your_drawable)
.setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setContentTitle(getText(R.string.app_name))
.setStyle(new NotificationCompat.InboxStyle()
.addLine("Needs to sync periodically. Long press to hide.")
.addLine(""))
.build();

startForeground(PRIMARY_FOREGROUND_NOTIF_SERVICE_ID, notification);
}

关于你的第二个问题:

AppWidget Provider的onReceive()方法由带有intents的广播触发,可以用来做不同的任务,部分更新appWidget,或者重启服务。因此,根据您提供的信息,您应该能够在提供商的 onReceive 区域进行网络调用,但您可能需要为其指定自定义 Intent 以触发 onReceive(),并确保更新所有实例appWidget 的更新远程 View 。例如,我们有几个自定义 Intent 触发 onReceive() 并部分更新我们的 appWidget:

在 appWidget 提供者中:

    // sample custom intent name    
public static final String ACTION_CLICK_ADVANCE_STATUS = "widget_action_click_advance_status";

...

@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);

if (ACTION_CLICK_ADVANCE_STATUS.equals(intent.getAction())) {
// update all instances of appWidgets
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, WidgetJobProvider.class));
// Do your work here
}

关于android - 来自 appWidget 的网络请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59049611/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com