如何在Android后台服务中运行cordova插件?

meh*_*sen 24 javascript mobile android webview cordova

我正在研究在cordova上开发的移动应用程序.我想实现一个后台服务,它做一些工作,比如打开套接字连接同步本地数据库和远程服务器,并通知用户新的远程推送等.关键是我在javascript中实现了这个代码,但我想在后台执行它.

我在互联网上搜索了一个cordova后台服务插件.

我已经阅读了一些关于android中后台服务的主题,这些是我发现的有用的:

所以我开始编写cordova插件(主要是在android上)来在后台执行javascript代码.我从后台服务创建了一个webview来执行它的javascript.这在我执行普通的javascript时工作正常但是当涉及到cordova插件时,它失败了,例如设备device.uuid给出的null.

这是java服务代码:

      public void onStart(Intent intent, int startId) {
      Toast.makeText(this, "My Happy Service Started", Toast.LENGTH_LONG).show();

           createBackGroundView();
           super.onStart(intent,startId);
    }


      public void createBackGroundView(){


        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
       LayoutParams params = new WindowManager.LayoutParams(
                   android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
                   android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
                   WindowManager.LayoutParams.TYPE_PHONE,
                   WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                   PixelFormat.TRANSLUCENT
           );

        params.gravity = Gravity.TOP | Gravity.LEFT;
        params.x = 0;
        params.y = 0;
        params.width = 200;
        params.height = 200;

        LinearLayout view = new LinearLayout(this);

        view.setLayoutParams(new RelativeLayout.LayoutParams(
                    android.view.ViewGroup.LayoutParams.MATCH_PARENT, 
                    android.view.ViewGroup.LayoutParams.MATCH_PARENT
            ));

        WebView wv = new WebView(this);
        wv.setLayoutParams(new LinearLayout.LayoutParams(
                    android.view.ViewGroup.LayoutParams.MATCH_PARENT,
                    android.view.ViewGroup.LayoutParams.MATCH_PARENT
            ));     
        view.addView(wv);
        wv.getSettings().setJavaScriptEnabled(true);
        wv.setWebChromeClient(new WebChromeClient());
            wv.loadUrl("file:///android_asset/www/background.html");
        wv.setWebViewClient(new WebViewClient() {

            @Override
            public void onReceivedError(final WebView view, int errorCode,
                    String description, final String failingUrl) {
                Log.d("Error","loading web view");
                super.onReceivedError(view, errorCode, description, failingUrl);
            }
        });

        windowManager.addView(view, params);

     }
Run Code Online (Sandbox Code Playgroud)

更新 logcat中没有错误.所以我试着在屏幕上写设备对象,这就是我得到的:

  document.write(JSON.stringify(window.device))
Run Code Online (Sandbox Code Playgroud)

这就是结果:

  { available : false, 
    plaform : null , 
    version : null , 
    uuid : null ,  
    cordova : null ,
    model : null 
   }
Run Code Online (Sandbox Code Playgroud)

我试图取代标准webViewcordovaWebView但同样的结果给出.

       //WebView wv = new WebView(this);  Commented out
       CordovaWebView wv = new CordovaWebView(this);
Run Code Online (Sandbox Code Playgroud)

有关此问题的任何帮助?

Jan*_*ker 5

您应该使用嵌入式 Cordova WebView,而不是标准 WebView。未设置标准 WebView 来处理 Cordova 插件,设备信息是一个插件。

请参阅有关嵌入 webviewsCordova 文档


Ric*_*ard 3

WebView 无法从后台服务执行 javascript。

我建议改用本机代码。但如果你必须使用 javascript,我会尝试这个库

https://code.google.com/p/jav8/

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("jav8");

  try {
    engine.eval("print('Hello, world!')");
  } catch (ScriptException ex) {
      ex.printStackTrace();
  } 
Run Code Online (Sandbox Code Playgroud)

首先将脚本的内容加载到字符串中,然后运行engine.eval()方法。

示例(从资产运行“test.js”):

AssetManager am = context.getAssets();
InputStream is = am.open("test.js");
BufferedReader r = new BufferedReader(new InputStreamReader(is));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
    total.append(line);
}

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("jav8");

  try {
    engine.eval(total.toString());
  } catch (ScriptException ex) {
      ex.printStackTrace();
  }
Run Code Online (Sandbox Code Playgroud)

注意!eval函数期望一次只执行一个 javascript 函数并返回该函数的值。