- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
目前,我的 AppWidgetProvider
有一个静态数据。用于传递信息 AppWidgetProvider
& RemoteViewsService.RemoteViewsFactory
public class MyAppWidgetProvider extends AppWidgetProvider {
// Key will be widget id
private static Map<Integer, Holder> holderMap = new java.util.concurrent.ConcurrentHashMap<Integer, Holder>();
public static int getClickedColumn(int appWidgetId) {
Holder holder = holderMap.get(appWidgetId);
if (holder == null) {
return -1;
}
return holder.clickedColumn;
}
public class AppWidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
@Override
public void onDataSetChanged() {
int clickedColumn = MyAppWidgetProvider.getClickedColumn(mAppWidgetId);
调用 AppWidgetProvider
的静态方法在大多数情况下都能正常工作。
但是,有时,如果我将小部件放在主屏幕上,让它在那里停留几个小时。当我回来并搜索 ListView
时,我可能会随机得到以下错误。
java.lang.ExceptionInInitializerError
at org.yccheok.project.gui.widget.AppWidgetRemoteViewsFactory.onDataSetChanged(AppWidgetRemoteViewsService.java:390)
at android.widget.RemoteViewsService$RemoteViewsFactoryAdapter.onDataSetChanged(RemoteViewsService.java:142)
at com.android.internal.widget.IRemoteViewsFactory$Stub.onTransact(IRemoteViewsFactory.java:49)
at android.os.Binder.execTransact(Binder.java:367)
at dalvik.system.NativeStart.run(Native Method)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at org.yccheok.project.gui.widget.MyAppWidgetProvider.<clinit>(MyAppWidgetProvider.java:564)
来自 <clinit>
, 我怀疑 MyAppWidgetProvider
被操作系统破坏了吗?这个原因AppWidgetRemoteViewsFactory
想在调用静态函数之前执行类初始化?
这是否意味着,MyAppWidgetProvider
可以随时被操作系统销毁,我们不应该在其中放置可共享的静态数据吗?
如果是这样,在 AppWidgetProvider
之间共享数据的正确方法是什么?和 RemoteViewsService.RemoteViewsFactory
? (除了使用文件或 SharedPreferences)
最佳答案
RemoteViewsFactory -> AppWidgetProvider
从 RemoteViewsFactory 到 AppWidgetProvider 的通信可以使用广播来完成,例如像这样:
Intent intent = new Intent(ACTION_PROGRESS_OFF);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
AppWidgetProvider 像这样接收事件:
@Override
public void onReceive(final Context context, final Intent intent) {
// here goes the check if the app widget id is ours
final String action = intent.getAction();
if (ACTION_PROGRESS_OFF.equals(action)) {
// turn off the refresh spinner
当然广播 Action 需要在manifest中定义:
<receiver
android:name="...">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="myPackage.ACTION_PROGRESS_OFF" />
</intent-filter>
<meta-data ... />
</receiver>
AppWidgetProvider -> RemoteViewsFactory
与 RemoteViewsFactory 通信的一种方式(在您的情况下可能是最好的方式)是按照您要传递给 RemoteViewsAdapter 的服务的 Intent 发送信息:
Intent intentRVService = new Intent(context, RemoteViewsService.class);
intentRVService.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
// let's put in some extra information we want to pass to the RemoteViewsFactory
intentRVService.putExtra("HELLO", "WORLD");
// when intents are compared, the extras are ignored, so we need to
// embed the extras into the data so that the extras will not be ignored
intentRVService.setData(Uri.parse(intentRVService.toUri(Intent.URI_INTENT_SCHEME)));
rv.setRemoteAdapter(appWidgetId, R.id.my_list, intentRVService);
rv.setEmptyView(R.id.my_list, android.R.id.empty);
// create the pending intent template for individual list items
...
rv.setPendingIntentTemplate(R.id.my_list, pendingIntentTemplate);
appWidgetMgr.notifyAppWidgetViewDataChanged(appWidgetId, R.id.my_list);
RemoteViewsService 可以轻松地从 Intent 中检索信息并将其传递给 RemoteViewsService.RemoteViewsFactory。
我不是 100% 确定您的小部件何时以及如何决定对数据进行排序,但我假设如果用户选择要排序的列,那么您必须使用 notifyAppWidgetViewDataChanged 完成更新周期,然后您将通过它列沿。如果您稍后需要该信息,则必须以某种方式存储该信息 (SharedPreferences)。
关于android - 在 AppWidgetProvider 和 RemoteViewsService.RemoteViewsFactory 之间共享数据的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22563153/
我的应用小部件在多种模式下运行。对于其中的每一种模式,我都创建了一个 RemoteViewsFactory。为了在模式之间切换,我向我的 AppWidgetProvider 发送了一个 Intent
我正在创建一个简单的 Android 小部件,用于从网站获取并显示一些电影封面。显示图像的 GridView 很简单。该小部件工作正常,但当我开始滚动时,我得到了 OutOfMemoryError 并
我已尽力按照 developer.android.com 上的说明进行操作但似乎我在某个地方犯了一个我无法弄清楚的愚蠢错误。 在连续记录之后,我意识到在我的 RemoteViewsFactory 实现
有一个带有 Listview 的 AppWidget,我想用 RemoteViewsService.RemoteViewsFactory 填充它。 我有以下错误 E/AndroidRuntime(12
我正在为我的应用程序开发小部件,它基于 StackView 并且应该显示一些项目。项目的数量可能会因用户操作而异——可以说这是某种收藏夹菜单。我已经实现了 RemoteViewsFactory 后代来
我正在为应用程序开发 Android 小部件,问题是我无法在 RemoteViewsFactory 中的按钮上设置 onClickPendingIntent()。 我解释一下:我创建了一个 AppWi
我在应用程序小部件中有一个应用程序启动器。我想从 RemoteViewsFactory 开始 Activity 。但它没有用。 这是我在 RemoteViewsFactory 中的代码: @Overr
我有一个显示图 block GridView 的 Android 应用小部件。每个图 block 都包含股票报价信息。我从网络服务器查询股票报价信息并将其存储在 ArrayList (stock_in
我创建了一个带有 ListView 的应用程序小部件。在 RemoteViewsFactory 类中,我从 SQLite 数据库填充列表。一切都很好,但是如果我在 updateWidget() 方法中
我想发布一个问题的解决方案。希望它能帮助其他面临同样问题的人。 这与可用的 Android 通用图像加载器库有关 here 原始问题是: 我今天开始使用你们的 Android Universal Im
有时,当我的小部件正在更新时,我会在日志中看到: .. getViewAt position = 7 getViewAt position = 7.. RemoteViews 对象第一次放在位置 0,
由于 RemoteViewFactory 中没有 getItemViewType() 方法 - 它实际上如何确定 ViewType? 我偶然发现了一个案例,我肯定只有 4 个 View 类型,但不断出
我有一个小部件,我试图用它在 ListView 中显示来 self 的应用程序本地数据库的信息。 我正在使用 RemoteViewsService.RemoteViewsFactory 接口(inte
目前,我的 AppWidgetProvider有一个静态数据。用于传递信息 AppWidgetProvider & RemoteViewsService.RemoteViewsFactory publ
我正在尝试获取一些最新的电影图像并将它们显示在 Android 应用小部件中,根据要求,小部件应每小时刷新一次以获取最新的电影图像。 由于我在整个应用程序中使用协程,因此我需要使用现有的具有挂起功能的
我正在尝试使用小部件实现 android 应用程序,但在 nexus 5 设备上发现了奇怪的行为(我有两个 - 一个是 Lollipop ,一个是棉花糖)。如果我调用 AppWidgetManager
我有一个 AppWidget,其中包含一个 StackView。除了 AppWidget,我还有一项服务,当用户将我的 AppWidget 添加到他们的主屏幕时启动,该服务每两小时轮询一次新数据。当服
我根据 android 文档开发了我的 AppWidget,在 onCreate() 中加载我的光标并在 onDataSetChanged() 中重新加载它,并且一切正常,直到我在 RemoteVie
我是一名优秀的程序员,十分优秀!