注册Darwin通知并通过Callback - Codename One发送活动详情

时间:2017-07-18 18:11:39

标签: ios codenameone

我正在尝试创建一个带有Codename One的测试App,它通过Darwin Notifications侦听displayStatus更改,并通过回调将事件发送到Java端。我对C的知识非常少,几乎不了解目标C,因此我对该部分的大部分代码都被提升并加入了网络中的几个地方。我遵循了开发人员指南,但构建在云上失败了。到目前为止,我已经完成了以下工作:

在我的开始方法中,我有这个:

public void start() {
    if(current != null){
        current.show();
        return;
    }
    Form hi = new Form("Xerveur", new LayeredLayout());

    hi.add(buildRootContainer()).add(buildRootChildContainer());

    Display.getInstance().callSerially(hi::show);
    registerForNativeCallback();
}

注册本机接口:

private void registerForNativeCallback(){
    NativeListener listener = NativeLookup.create(NativeListener.class);
    if( listener != null && listener.isSupported() ){
        Log.p("Setup Event Listener returned: " + listener.setupEventListener());
    }
}

以上代码段位于主类文件中。 NativeListener接口很简单:

public interface NativeListener extends NativeInterface {
    public boolean setupEventListener();
}

现在我有一个简单的回调类,它应该接收一个字符串,从本机端获得所需的信息:

public class NativeCallback {
    public static void receive(String payload){
        Log.p(payload);
    }
}

这些是生成的“.m”文件的内容(“.h”文件未自动生成)并且我编辑过:

#import "ca_ratelsoft_testing_testapp2_NativeListenerImpl.h"
#include "ca_ratelsoft_testing_testapp2_NativeCallback.h"
#include "CodenameOne_GLViewController.h"
#include <unistd.h>       // good idea in general
#include <stdlib.h>       // good idea in general

#include <CoreFoundation/CoreFoundation.h>
#include <notify.h>       // for all notifications


@implementation ca_ratelsoft_testing_testapp2_NativeListenerImpl

-(BOOL)setupEventListener{
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                        NULL, // observer
                                        displayStatusChanged, // callback
                                        CFSTR("com.apple.springboard.displayStatus"), // event name
                                        NULL, // object
                                        CFNotificationSuspensionBehaviorDeliverImmediately);

    return YES;
}

static void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
    NSLog(@"event received!");
    // you might try inspecting the `userInfo` dictionary, to see
    //  if it contains any useful info
    if (userInfo != nil) {
        const void * keys;
        const void * values;
        NSString *payload = @"displayStatus$$$";    //delimeter: $$$
        CFDictionaryGetKeysAndValues(userInfo, &keys, &values);

        //key1=value1;key2=value2;

        for (int i = 0; i < CFDictionaryGetCount(userInfo); i++) {
            const char * keyStr = CFStringGetCStringPtr((CFStringRef)&keys[i], CFStringGetSystemEncoding());
            const char * valStr = CFStringGetCStringPtr((CFStringRef)&values[i], CFStringGetSystemEncoding());
            if( i > 0 )
                payload = [payload stringByAppendingString:@";"];
            payload = [payload stringByAppendingString:@(keyStr)];
            payload = [payload stringByAppendingString:@"="];
            payload = [payload stringByAppendingString:@(valStr)];
        }

        ca_ratelsoft_testing_testapp2_NativeCallback_receive___java_lang_String(CN1_THREAD_GET_STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG payload));
    }
}

-(BOOL)isSupported{
    return YES;
}

@end

构建调试iOS应用时出现以下错误:https://www.dropbox.com/s/sq8f00nzf445gp0/f9e35511-c43f-4bb6-854a-f513ec8e3820-1500397464685-error.txt?dl=0

1 个答案:

答案 0 :(得分:1)

首先让我们从错误开始,如果你滚动到底部,你会看到提到NativeListenerImpl.o。如果您在文件中搜索NativeListenerImpl,您将看到该文件的编译代码及其下方的实际错误:

src/ca_ratelsoft_testing_testapp2_NativeListenerImpl.m:2:10: fatal error: 'ca_ratelsoft_testing_testapp2_NativeCallback.h' file not found
#include "ca_ratelsoft_testing_testapp2_NativeCallback.h"
         ^
1 error generated.

这是因为我们的优化器过于急于删除未使用的代码,并且无法找到回调的用法。您可以通过将以下代码添加到主类来解决此问题:

boolean fakeVariable;

public void init(Object o) {
  // ... rest of code

  if(fakeVariable) {
      NativeCallback.receive(null);
  }
}

这很重要。不要将变量设为私有!!!

变量受包保护,并且始终为false,因此代码永远不会发生。理论上,一些代码可以更改该标志,以便优化器无法检测到该标志,并且将被强制保留该代码。