在移植gecko的时候发现一些问题,比如gecko连alert对话框这种基本的控件都没有默认实现,包括b2g,在firefox os(那个ui叫gaia)中是纯粹地用html实现的。起初觉得把gaia的的代码,拷过来点就是了,后来发现gaia写得有点复杂,会产生很多依赖,还不如直接用native的控件来实现。做法是参考android的firefox,用js处理部分逻辑,gui相关部分用java,就会产生js调java的需求。我是要js调c++,做法差不多。
android中有一个叫AndroidBridge的类,把它注册为一个service,js就调用这个类的handleGeckoMessage()方法。这里简单介绍下操作步骤
1. widget/YOUR_OS/nsINativeBridge.idl
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, uuid(0e93d8f4-5392-48bc-9f4d-3a151773b14c)]
interface nsINativeBridge : nsISupports
{
AString handleGeckoMessage(in AString message);
};
XPIDLSRCS = \
nsINativeBridge.idl
3.加入nsNativeBridge.h和nsNativeBridge.cpp。其实在idl生成的头文件的注释里包含了如何写这些文件的方法,稍微改改就行
widget/YOUR_OS/nsNativeBridge.h:
#ifndef nsNativeBridge_h__
#define nsNativeBridge_h__
#include "nsINativeBridge.h"
#define NS_NATIVEBRIDGE_CID \
{ 0x6a63ba66, 0xc72f, 0x431f, \
{ 0xb9, 0x7d, 0x42, 0x0b, 0xa5, 0xde, 0x19, 0xf5 } }
class nsNativeBridge : public nsINativeBridge
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSINATIVEBRIDGE
nsNativeBridge();
private:
~nsNativeBridge();
protected:
};
#endif
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsNativeBridge.h"
#include "nsDOMClassInfoID.h"
NS_IMPL_ISUPPORTS1(nsNativeBridge, nsINativeBridge)
nsNativeBridge::nsNativeBridge()
{
}
nsNativeBridge::~nsNativeBridge()
{
}
/* void handleGeckoEvent (in AString message); */
NS_IMETHODIMP nsNativeBridge::HandleGeckoMessage(const nsAString & message, nsAString &aRet)
{
nsCString cMessage = NS_ConvertUTF16toUTF8(message);
aRet = NS_ConvertUTF8toUTF16(gGeckoAppShellFuncs->handleGeckoMessage(cMessage.get()));
return NS_OK;
}
在nsWidgetFactory.cpp中注册.
加上
#include "nsNativeBridge.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeBridge)
NS_DEFINE_NAMED_CID(NS_NATIVEBRIDGE_CID);
在 static const mozilla::Module::CIDEntry kWidgetCIDs[] 加上
{ &kNS_NATIVEBRIDGE_CID, false, NULL, nsNativeBridgeConstructor },
{ "@mozilla.org/native/bridge;1", &kNS_NATIVEBRIDGE_CID },
在js中调用nsNativeBridge就是通过上面的contract id
4. 在Makefile.in中加上新增的cpp
const Cc = Components.classes;
let data = Cc["@mozilla.org/native/bridge;1"].getService(Ci.nsINativeBridge).handleGeckoMessage(JSON.stringify({ gecko: aMsg }));
注:这里js是gecko启动时调用的那些js,比如核心的shell.js,用户使用的js直接用js扩展好了