【问题标题】:WakefulBroadcastReceiver startWakefulService fails to proceedWakefulBroadcastReceiver startWakefulService 无法继续
【发布时间】:2016-12-29 12:37:10
【问题描述】:

我的应用不会调用来自 wakefulbroadcastreceiver 的 intentservice 请求

清单:

        <service
        android:name=".MyWearableListenerService">
        <intent-filter>
            <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
            <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED"/>
            <data android:scheme="wear" android:host="*"/>
        </intent-filter>
    </service>

    <service
        android:name=".CounterActivity$WearableReceiverService"
        android:exported="false">
    </service>

    <receiver
        android:name=".CounterActivity$WearableReceiver"
        android:enabled="true">
    </receiver>

所以我注册了所有接收器和服务。

在我的主要活动中,我将这些作为主类中的子类,因此我可以调用主类 msgReqAction() 中的方法

public class WearableReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service = new Intent(context, WearableReceiverService.class);
        startWakefulService(context, service);
    }
}

public class WearableReceiverService extends IntentService {

    public WearableReceiverService(){
        super("WearableReceiverService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));
        WearableReceiver.completeWakefulIntent(intent);
    }
}

我不认为将这些作为子类会妨碍这种情况,但它可能会。如果我必须将这些放在主类之外进行操作,请告诉我。

最后,我从主要活动之外的侦听器开始整个过程​​,该侦听器侦听来自可穿戴设备的消息

@Override
public void onMessageReceived(final MessageEvent messageEvent) {
    nodeId = messageEvent.getSourceNodeId();
    String incomingPath = messageEvent.getPath();
    int incomingReq = Integer.parseInt(new String(messageEvent.getData()));

    if(incomingPath.equalsIgnoreCase(MyConstants.MSG_COUNTER_REQ_PATH)) {
        Intent broadcastIntent = new Intent();
        broadcastIntent.setAction(MyConstants.BROADCAST_ACTION_RESP);
        broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
        broadcastIntent.putExtra(MyConstants.BROADCAST_DATA_REQ, incomingReq);
        sendBroadcast(broadcastIntent);

    }else if(incomingPath.equalsIgnoreCase(MyConstants.MSG_DEFAULT_PATH)){

    }
}

public static final String BROADCAST_ACTION_RESP = "com.example.johnbravado.zionwork.MESSAGE_PROCESSED";

我的项目是 com.example.johnbravado.zionwork - 顺便说一句,有没有办法在 android studio 中轻松更改和重构它,以便我可以摆脱示例或完全更改它?

当我运行调试器时,系统会一直运行到

startWakefulService(context, service);

然后它在没有进入意图服务的情况下崩溃。在所有这一切中,我是否缺少一些简单的东西来阻止它进入服务和工作。我能说的最好的是它根本没有进入服务。我添加了一些服务的介绍行

@Override
protected void onHandleIntent(Intent intent) {
    int data;
    data = 0;
    data++;
    msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));
    WearableReceiver.completeWakefulIntent(intent);
}

并尝试在这些行上运行调试点,但没有到达那里。

【问题讨论】:

    标签: android android-intent android-service wear-os android-broadcastreceiver


    【解决方案1】:

    您不能将Service 定义为非静态内部类。

    非静态内部类包含对其外部类的引用。这意味着为了创建内部类的新实例,您需要有一个外部类的实例。

    当 Android 尝试启动您的 Service 时,它会尝试创建内部类的新实例。这失败了,因为 Android 没有在创建中使用的外部类的实例。

    同样的规则适用于BroadcastReceiver

    解决方案:将所有内部类移动到成熟的类(在它们自己的源文件中)。

    【讨论】:

    • 无论如何我可以从外部服务调用该 msgReqAction()。当设备进入睡眠模式时服务与主要活动一起工作的点。或者唯一真正的方法是制作一些服务可以引用的静态变量,然后在调用 onResume() 时在主活动中对睡着时发生的事情进行所需的操作。
    • 您可以作弊并让Activity 将对自身的引用存储在static 变量中,以便Service 可以对其调用方法。但是,这是不好的做法。通常,Service 通过发送广播Intents(Activity 正在侦听)或通过将Activity 绑定到Service 并提供从Service 到@ 的回调来与活动通信987654333@ 使用 AIDL 或使用 EventBus 之类的东西(这是一个发布/订阅框架)
    • 我认为这就是我的广播接收器正在做的事情。如果我将唤醒广播与普通广播交换并删除辅助服务的使用并仅处理广播接收器中的 msgReqaction() 就可以了。或者如果不是主要活动的一部分,我将如何让广播接收器与主要活动一起工作。
    • 抱歉,我对您的所有组件都有些困惑。通常,您使用WakefulBroadcastReceiver,如果您想知道的事情发生时(以及您的应用程序可能未运行),手机可能处于睡眠状态,Android 框架将触发该WakefulBroadcastReceiver。这在触发Service 以执行进一步处理时持有唤醒锁。如果您只想在应用程序运行时捕获这些事件,那么您应该在您的 Activity 中创建一个 BroadcastReceiver 的实例并注册它以侦听您感兴趣的事件。在这种情况下,. ..
    • ... BroadcastReceiver 可以是一个内部类,不需要添加到清单中,因为它不会被Android框架实例化。请解释您的组件应该如何交互。我有点迷茫,尤其是根据您发布的代码。
    【解决方案2】:

    解决方案是消除 WakefulfulBroadcastReceiver 和辅助 IntentService。相反,我使用 BroadcastReceiever 并直接从 Wearable 侦听器函数发送广播,并使用它直接在活动中处理数据。

    public class WearableReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            //Intent service = new Intent(context, WearableReceiverService.class);
            //startWakefulService(context, service);
            PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
            PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                    "com.example.johnbravado.zionwork");
            wakeLock.acquire();
            // Do Work
            msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));
    
            wakeLock.release();
        }
    }
    

    即使我做的不多,但必然需要唤醒锁。如果我以后决定做更多的工作,我已经准备好了。我不确定这是否是唤醒锁的最佳位置,或者从未真正使用过它们,但这是另一个话题。

    我还删除了清单文件中对额外服务和接收器的引用。现在效果很好

    【讨论】:

      猜你喜欢
      • 2013-02-09
      • 2016-12-25
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多