[英]Delphi Android Firebase Cloud Messaging : Application crashes on notification receive
我使用 Delphi Rio 10.3.2。 我遵循了本教程: http://docwiki.embarcadero.com/RADStudio/Rio/en/Firebase_Android_Support
所以在主窗体中,我添加了 OnServiceConnectionChange、OnReceiveNotificationEvent。
OnServiceConnectionChange 只是给我使用 logcat 的设备令牌。
procedure TfAccueil.OnServiceConnectionChange(Sender: TObject;PushChanges: TPushService.TChanges);
var
PushService: TPushService;
token : string;
url : string;
begin
PushService := TPushServiceManager.Instance.GetServiceByName(TPushService.TServiceNames.GCM);
if TPushService.TChange.DeviceToken in PushChanges then begin
token := PushService.DeviceTokenValue[TPushService.TDeviceTokenNames.DeviceToken];
if FDeviceToken <> token then begin
FDeviceToken := token;
fData.Log('#FCM','FireBase Device Token: ' + FDeviceToken);
end;
end;
if (TPushService.TChange.Status in PushChanges) and (PushService.Status = TPushService.TStatus.StartupError) then begin
fData.Log('#FCM','Error: ' + PushService.StartupError);
end;
end;
获得设备令牌后,我使用 Postman(其中 XXX 是设备令牌)测试通知:
{
"registration_ids" : ["XXX"],
"data" : {
"key_1" : "Value for key_1",
"key_2" : "Value for key_2"
}
}
在 OnReceiveNotificationEvent 中,我收到了我发送的内容。
procedure TfAccueil.OnReceiveNotificationEvent(Sender: TObject; const ServiceNotification: TPushServiceNotification);
begin
fData.Log('#FCM','-----------------------------------------');
fData.Log('#FCM','DataKey = ' + ServiceNotification.DataKey);
fData.Log('#FCM','Json = ' + ServiceNotification.Json.ToString);
fData.Log('#FCM','DataObject = ' + ServiceNotification.DataObject.ToString);
fData.Log('#FCM','---------------------------------------');
end;
收到的数据显示在 logcat 中,我看到“key_1”和“key_2”的值。
PostMan 显示正确响应:
{
"multicast_id": 1194574639982246633,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [
{
"message_id": "0:1591625227805806%7de42328f9fd7ecd"
}
]
}
但是,应用程序崩溃了,它停止响应,我在 logcat 中得到了这个:
06-08 16:01:55.461: I/info(19398): -----------------------------------------
06-08 16:01:55.461: W/System.err(19398): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
06-08 16:01:55.461: I/info(19398): DataKey = fcm
06-08 16:01:55.461: I/info(19398): Json = {"google.delivered_priority":"normal","google.sent_time":"1591624915033","google.ttl":"2419200","google.original_priority":"normal","from":"697029724431","key_1":"Value for key_1","key_2":"Value for key_2","google.message_id":"0:1591624915047510%7de42328f9fd7ecd","google.c.sender.id":"697029724431"}
06-08 16:01:55.461: I/info(19398): DataObject = {"google.delivered_priority":"normal","google.sent_time":"1591624915033","google.ttl":"2419200","google.original_priority":"normal","from":"697029724431","key_1":"Value for key_1","key_2":"Value for key_2","google.message_id":"0:1591624915047510%7de42328f9fd7ecd","google.c.sender.id":"697029724431"}
06-08 16:01:55.461: I/info(19398): ---------------------------------------
06-08 16:01:55.462: W/System.err(19398): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6898)
06-08 16:01:55.462: W/System.err(19398): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1048)
06-08 16:01:55.462: W/System.err(19398): at android.view.View.requestLayout(View.java:19785)
06-08 16:01:55.462: W/System.err(19398): at android.view.View.requestLayout(View.java:19785)
06-08 16:01:55.462: W/System.err(19398): at android.view.View.requestLayout(View.java:19785)
06-08 16:01:55.462: W/System.err(19398): at android.view.View.requestLayout(View.java:19785)
06-08 16:01:55.462: W/System.err(19398): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
06-08 16:01:55.462: W/System.err(19398): at android.view.View.setFlags(View.java:11482)
06-08 16:01:55.462: W/System.err(19398): at android.view.View.setVisibility(View.java:8069)
06-08 16:01:55.462: W/System.err(19398): at com.embarcadero.rtl.ProxyInterface.dispatchToNative(Native Method)
06-08 16:01:55.462: W/System.err(19398): at com.embarcadero.rtl.ProxyInterface.invoke(ProxyInterface.java:21)
06-08 16:01:55.462: W/System.err(19398): at java.lang.reflect.Proxy.invoke(Proxy.java:813)
06-08 16:01:55.462: W/System.err(19398): at $Proxy8.onNotificationReceived(Unknown Source)
06-08 16:01:55.462: W/System.err(19398): at com.embarcadero.firebase.messaging.ProxyFirebaseMessagingService.onMessageReceived(ProxyFirebaseMessagingService.java:35)
06-08 16:01:55.462: W/System.err(19398): at com.google.firebase.messaging.FirebaseMessagingService.zzd(Unknown Source)
06-08 16:01:55.462: W/System.err(19398): at com.google.firebase.iid.zzc.run(Unknown Source)
06-08 16:01:55.462: W/System.err(19398): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
06-08 16:01:55.463: W/System.err(19398): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
06-08 16:01:55.463: W/System.err(19398): at com.google.android.gms.common.util.concurrent.zza.run(Unknown Source)
06-08 16:01:55.463: W/System.err(19398): at java.lang.Thread.run(Thread.java:761)
06-08 16:01:55.478: W/System.err(19398): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
06-08 16:01:55.478: W/System.err(19398): at android.os.Handler.<init>(Handler.java:200)
06-08 16:01:55.478: W/System.err(19398): at android.os.Handler.<init>(Handler.java:114)
06-08 16:01:55.478: W/System.err(19398): at android.view.SurfaceView$1.<init>(SurfaceView.java:131)
06-08 16:01:55.478: W/System.err(19398): at android.view.SurfaceView.<init>(SurfaceView.java:131)
06-08 16:01:55.478: W/System.err(19398): at android.view.SurfaceView.<init>(SurfaceView.java:207)
06-08 16:01:55.478: W/System.err(19398): at android.view.SurfaceView.<init>(SurfaceView.java:203)
06-08 16:01:55.478: W/System.err(19398): at android.view.SurfaceView.<init>(SurfaceView.java:199)
06-08 16:01:55.478: W/System.err(19398): at com.embarcadero.firemonkey.form.FormView.<init>(FormView.java:16)
06-08 16:01:55.478: W/System.err(19398): at com.embarcadero.rtl.ProxyInterface.dispatchToNative(Native Method)
06-08 16:01:55.478: W/System.err(19398): at com.embarcadero.rtl.ProxyInterface.invoke(ProxyInterface.java:21)
06-08 16:01:55.479: W/System.err(19398): at java.lang.reflect.Proxy.invoke(Proxy.java:813)
06-08 16:01:55.479: W/System.err(19398): at $Proxy8.onNotificationReceived(Unknown Source)
06-08 16:01:55.479: W/System.err(19398): at com.embarcadero.firebase.messaging.ProxyFirebaseMessagingService.onMessageReceived(ProxyFirebaseMessagingService.java:35)
06-08 16:01:55.479: W/System.err(19398): at com.google.firebase.messaging.FirebaseMessagingService.zzd(Unknown Source)
06-08 16:01:55.479: W/System.err(19398): at com.google.firebase.iid.zzc.run(Unknown Source)
06-08 16:01:55.479: W/System.err(19398): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
06-08 16:01:55.479: W/System.err(19398): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
06-08 16:01:55.479: W/System.err(19398): at com.google.android.gms.common.util.concurrent.zza.run(Unknown Source)
06-08 16:01:55.479: W/System.err(19398): at java.lang.Thread.run(Thread.java:761)
关键在这里: W/System.err(19398): android.view.ViewRootImpl$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及它的视图
但我不知道出了什么问题……我错过了什么? 我什至不进行任何 UI 更新。
注意我还尝试删除 OnReceiveNotificationEvent 中的所有代码,即所有带有“fData.Log(...)”的行,但我得到相同的结果,相同的 logcat(当然没有我的数据日志)。
经过一番研究,这个问题是由另一个程序监听来自另一个应用程序的通知并进行一些 UI 更新引起的,这就解释了为什么应用程序抱怨线程试图“触摸”视图。
procedure TfData.HandleActivityMessage(const Sender: TObject; const M: TMessage);
begin
if M is TMessageReceivedNotification then begin
HandleIntentAction(TMessageReceivedNotification(M).Value);
end;
end;
function TfData.HandleIntentAction(const Data: JIntent): Boolean; var bc : string; begin Result := False; if Data <> nil then begin if Data.hasExtra(StringToJString(bcDatawedgeData)) then begin //---> I ADDED THIS TEST bc := JStringToString(Data.getStringExtra(StringToJString(bcDatawedgeData))); result := true; bcScan(bc); end; end; end;
推送通知也会触发此代码。 所以我添加了测试 (Data.hasExtra(StringToJString(bcDatawedgeData))) 以确保在推送通知的情况下不执行代码。
这解决了问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.