AppWidgetProvider 和 RemoteViewsService.RemoteViewsFactory 之间共享数据的正确方法是什么

2024-04-25

目前,我的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);

Calling 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)

From <clinit>, 我猜测MyAppWidgetProvider被操作系统破坏了?这个原因AppWidgetRemoteViewsFactory想要在调用静态函数之前执行类初始化?

意思是不是,MyAppWidgetProvider可以随时被操作系统销毁,我们不应该在其中放置可共享的静态数据吗?

如果是这样,之间共享数据的正确方法是什么?AppWidgetProvider and RemoteViewsService.RemoteViewsFactory? (除了使用文件或共享首选项之外)


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

当然广播动作需要在清单中定义:

<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 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 可以轻松地从意图中检索信息并将其传递给 RemoteViewsService.RemoteViewsFactory。

我不是 100% 确定您的小部件决定何时以及如何对数据进行排序,但我假设如果用户选择要排序的列,那么您必须使用 notificationAppWidgetViewDataChanged 经历更新周期,然后您将传递该列。如果您稍后需要该信息,则必须以某种方式存储该信息(SharedPreferences)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AppWidgetProvider 和 RemoteViewsService.RemoteViewsFactory 之间共享数据的正确方法是什么 的相关文章

  • 如何使用 Android Studio 2.1.3 从 Android 中的文本文件中获取随机行?

    我有一个 500 行的文本文件 我将此文本文件放置在 app src main assets 文件夹中 名称为 words txt 在此文件中 每一行都用换行符分隔 现在我需要从这个文本文件中获取随机行 在发布此内容之前 我访问了以下问题
  • 如何在GreenDao中实现表继承

    我一直在尝试创建一个数据库 其中所有表都继承某个元素 以便有可能拥有元数据 我在模型生成器的所有表声明中添加了这一行 public Entity addSuperEntity Schema schema Entity superEntity
  • 如何从 Android 广播接收器显示对话框?

    理想情况下 我不想启动一项活动来执行此操作 当 WiFi 连接丢失时 我的应用程序需要关闭 因为这对我们来说是一个致命错误 我想显示一条错误消息并让用户按 确定 按钮 然后退出应用程序 解决这个问题的最佳方法是什么 Thanks AFAIK
  • 如何从 BroadcastReceiver 刷新 ListView?

    如果我打电话notifyDataSetChanged 在与我的 ListView 关联的自定义适配器上 所有视图都应该自行刷新 getView 将被调用 现在我有一个正在监听事件的 BroadcastReceiver 当事件触发时 List
  • 如何生成带logo的二维码?

    我正在为 Android 设备开发应用程序 我想生成带有徽标的二维码 With ZXing I know how to generate simple QR codes like this one But I want to generat
  • 将实时 Android 网络摄像头视频上传到 RTP/RTSP 服务器

    我已经做了适当的研究 但仍然缺乏关于我想要实现的目标的信息 因此 我想编写一个应用程序 用户可以在其中录制视频并立即 实时 将视频上传到 RTP RTSP 服务器 服务器端不会有问题 我不清楚的是如何在手机端实现这一点 到目前为止 我的研究
  • 何时使用支持库

    我对 Android 支持库的用途和何时需要它感到困惑 据我了解 使用支持库的主要优点是 Android 可以在旧版本中自行实现主题和 UI 功能 而无需开发人员显式定义它们 这些关键的 UI 功能之一是操作栏 它是为 Honeycomb
  • Glide:如何使用 Glide v4 调整 gif 大小并将其另存为文件?

    我想调整 gif 文件的大小并保存它 我尝试使用一些建议的方法 但这些方法给出了错误 后来我知道有些方法在 Glide 中已被弃用v4 byte bytes Glide with context asGif load url toBytes
  • Android 自定义对话框中的图标

    有没有一种方法可以在不使用 AlertDialog 方法的情况下在自定义对话框上设置图标 对话框有标题 但缺少漂亮的分隔线和设置图标的功能 但肯定有一种方法可以在不使用 AlertDialog 的情况下获得两者 您可以使用以下代码添加图标
  • OnSharedPreferenceChangeListener 未调用 #2

    好吧 我开始从 Google 的 android 实现这个可怕的代码 未调用 OnSharedPreferenceChangeListener 这是我的代码 你能建议一下吗 类定义 private SharedPreferences sPr
  • 是否可以在 Flutter 中创建自定义快速设置图块?

    我搜索了 Flutter 文档并用谷歌搜索了这个 但结果为零 我正在开发我的第一个 Android Flutter 应用程序 我想为其创建一个自定义的快速设置图块 我的目标是牛轧糖及以上 我知道这在 Java 和 Kotlin 中是可能的
  • 使用 Android Intent 发送基于 HTML 的电子邮件正文

    我需要使用 android Intent extra 将基于 HTML 的内容发送到电子邮件应用程序 它接受一些标签 例如 br 但它没有显示任何锚链接或 h1 其显示像简单的文本 EDITED I have tried with gmai
  • Android 是否可以获取用户和设备所在国家/地区的货币代码?

    是否可以获取用户和设备所在国家 地区的货币代码 我想将用户当前国家 地区的国家 地区代码设置为默认国家 地区 我们在 Android 中有解决方案吗 由于这段代码可能对您有帮助 public class CurrencyTest publi
  • Android 应用安装验证

    我有一个应用程序 其中列出了用户可以安装并赚取积分的一些活动 应用程序列表 现在我主要关心的是安全性 一些用户从模拟器或VPN或其他东西安装应用程序 这样我的客户就无法在Google Play商店中安装应用程序 我见过一些应用程序 如现金海
  • 我如何在 Android 中跟踪收到的短信?

    我正在开发一个应用程序 想要跟踪传入的短信 我需要一个可以使用的示例代码或例程 如果您为传入短信实施广播接收器 在这种情况下 以下代码将跟踪您传入的短信并为您提供消息和发件人号码 import android content Broadca
  • 在 Android 谷歌地图中绘制 4K 折线

    我现在正在开发一个适用于 Android 设备的应用程序 主要功能是在地图上绘制折线以显示城市中每条街道的交通情况 不幸的是 当我绘制大约 3K 折线时 数量会根据屏幕尺寸和缩放级别而减少 我的地图变得非常慢 我没有提及绘制所有线条的时间
  • 如何检查Android应用程序是否第一次打开

    我想在用户第一次打开应用程序时有一个弹出窗口 如何查看 获取应用程序被打开的次数 请帮忙 多谢 当您的应用程序启动时 在onCreate 方法 您可以检查 SharedPreference 是否存在 如果没有 则这是该应用程序第一次启动 然
  • Android - 使用 HttpURLConnection 来 POST XML 数据

    我遇到了一些死胡同 需要一些帮助 请 我对 Android 开发 以及一般编码 非常陌生 基本上我需要使用 HttpURLConnection 将 XML 数据发布到 URL 但无法让它工作 我的应用程序从 GET 请求读取并传递 XML
  • 获取 Search.List 中的 ViewCount - Youtube 数据 API v3

    最近 我与youtube API v3 for Android I use 搜索列表 https developers google com youtube v3 docs search list当我想从关键字检 索视频列表时 我可以从结果
  • Android 6.0.1 无法以编程方式启用 wifi 热点

    当我尝试通过以下代码启用 wifi 网络共享时 它会抛出异常 com java lang reflect Method invoke Native Method 处的 java lang reflect InitationTargetExc

随机推荐

  • 32x8 寄存器文件 VHDL 测试台

    我已经用 vhdl 编写了该电路的汇编代码 我想用测试台来模拟它 RegWrite 1 位输入 时钟 写寄存器个数 3位输入 写地址 写入数据 32 位输入 数据输入 读取 寄存器编号 A 3 位输入 读取地址 读取寄存器编号 B 3 位输
  • Spring Cloud 配置服务器无法使用本地属性文件

    我一直在玩弄位于此处的 github 上的 Spring Cloud 项目 https github com spring cloud spring cloud config https github com spring cloud sp
  • redis-cli 重定向到 127.0.0.1

    我在PC1上启动Redis集群 然后在PC2上连接它 当需要重定向到另一个集群节点时 它会显示Redirected to slot 7785 located at 127 0 0 1 但应该显示Redirected to slot 7785
  • 壁纸更换事件

    我可以在广播接收器中获取壁纸更改事件吗 我需要检测用户是否更改了壁纸 我怎样才能做到呢 我正在做的是这样的 我有一个可以自动更改壁纸的应用程序 如果用户使用不同的应用程序手动更改它 我想注意到它并询问用户是否要将新壁纸添加到我的应用程序的列
  • Kafka 消费者通过 JMX 滞后

    我正在尝试监控 Kafka 0 10 中消费者组的滞后情况 我们的消费者在 Kafka 而不是 ZooKeper 中跟踪他们的偏移量 这意味着我可以使用以下方式获取数据 bin kafka consumer groups sh bootst
  • 如何在 QScrollArea() 之上显示 QPropertyAnimation()?

    1 Intro 我工作于Python 3 7在 Windows 10 上并使用PyQt5对于图形用户界面 在我的申请中 我得到了一个QScrollArea 里面有一系列按钮 单击时 按钮必须移到该区域之外 我用一个QPropertyAnim
  • Spark Shell 监听本地主机而不是配置的 IP 地址

    我正在尝试通过 Spark Shell 运行一个简单的 Spark 作业 它看起来像 Spark shell 的 BlockManager 侦听本地主机而不是配置的 IP 导致 Spark 作业失败的地址 抛出的异常是 无法连接到本地主机
  • 尝试从 Delphi 打开 Excel 或 Word 时出现“接口不受支持”错误

    当使用旧的 Delphi 代码将一些文本输出到 Excel 或 Word 时 我在一台机器上遇到了 接口不支持 错误 我怎样才能解决这个问题 问题是计算机上以前版本的 Excel 未正确卸载 为了修复它 我使用了遵循指示 http soci
  • 启动日志“未找到事务管理器”

    当我启动jetty时 日志中出现以下行 INFO oejpw PlusConfiguration No Transaction manager found if your webapp requires one please configu
  • JavaScript/jQuery - offsetLeft 和 offsetTop

    当鼠标悬停在跨度上时 我想获取 offsetLeft 和 offsetTop 值 以便我可以将某些东西悬停在它附近 当我这样做时 两个值都为 0 有什么更好的方法来解决这个问题 我正在使用 jQuery 假设我开始 由服务器端脚本循环 sp
  • 基类和派生类中的数据成员相同

    我是 C 编程新手 我正在阅读继承概念 我对继承概念有疑问 如果基类和派生类具有相同的数据成员 会发生什么 另外请仔细阅读我的代码 如下所示 include stdafx h include
  • Flutter - 带有 SafeArea 的系统栏颜色

    我正在尝试添加SafeArea带有彩色系统栏的 flutter 应用程序的小部件 但不知何故它们总是变黑 override Widget build BuildContext context SystemChrome setSystemUI
  • powershell函数输出到变量

    我在 powershell 2 0 中有一个名为 getip 的函数 它可以获取远程系统的 IP 地址 function getip strComputer computername colItems GWMI cl Win32 Netwo
  • '迭代时不能对不可变值使用变异 getter:'self' 是不可变的'?

    有谁知道为什么self indexCount in the ForEach给出了错误Cannot use mutating getter on immutable value self is immutable错误 我可以提供aView w
  • 移动视口尺寸是否大于屏幕尺寸?

    我在谷歌上搜索了移动视口 发现它是一个虚拟窗口 大多数移动浏览器都在其中渲染页面 视口比屏幕宽 here https developer mozilla org en docs Mozilla Mobile Viewport meta ta
  • 如何使用 C++ 获取 Windows 中的应用程序数据路径?

    我查遍了互联网 似乎没有找到合适的解决方案 我希望能够在 C 中以编程方式获取路径 ALLUSERSPROFILE Application Data 资源管理器可以将其转换为真实路径 我可以在不依赖第三方代码的情况下做到这一点吗 Use S
  • 复制带有格式的 Notepad++ 文本?

    我正在使用 Notepad 来编写代码 如何复制 Notepad 中的代码及其格式以粘贴到 Microsoft Word 中 即语法突出显示等 这是当您选择要复制为 html 的文本时来自 notepad 的图像 and how the f
  • hasattr 被称为方法,但它看起来像函数[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在 Python 中 函数接受参数并可选择返回信息 functionname param1 param2 returnvalue functio
  • 如何获取旋转器中的项目数量?

    如何动态获取微调器中的项目数 你可以试试 mSpinner getAdapter getCount
  • AppWidgetProvider 和 RemoteViewsService.RemoteViewsFactory 之间共享数据的正确方法是什么

    目前 我的AppWidgetProvider有静态数据 它用于传递信息AppWidgetProvider RemoteViewsService RemoteViewsFactory public class MyAppWidgetProvi