为OSGi包完全支持Android [英] Full Android support for OSGi bundles

查看:566
本文介绍了为OSGi包完全支持Android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此主题介绍了如何改造一个OSGi框架,在Android上运行。 然后给出提示转换成Android包为OSGi包能够调用的Andr​​oid API的。

This topic explains how you can transform an OSGI framework to run on android. Then it gives tips to convert android packages as OSGI bundles capable of calling android API.

在目前阶段,这些Android的OSGi bundle了不能做的唯一事情就是操纵活动和使用资源和资产。 我一直在努力解决这个限制。我希望有关于这个问题的好消息。

At the current stage, the only thing these Android OSGI bundles cannot do is manipulate activities and use resources and assets. I am continuously working at fixing this limitation. I hope to have good news on this subject.

我觉得比较难用在Eclipse中创建插件项目设施比将标准的Andr​​oid封装为OSGi包,所以我不会多谈了。

I found more difficult to use the Create Plugin project facility in Eclipse than converting standard android packages as OSGI bundles so I won't talk much about it.

您可以在此消息的结尾跟踪我的日志部分成果。

You can keep track of my achievements in the Log section at the end of this message.

我指的是 Knopflerfish 的项目,因为它的基础是我的工作。的修改,目的是要在 Knopflerfish OSGi的机器人项目,但实际执行适用于其他的OSGI框架。没有必要对OSGi框架本身的修改,我们将只更新该项目 KfServiceLib KfBasicApp 工具目录Knopflerfish分布。

I am referring to Knopflerfish projects because it was the basis for my work. The modifications are meant to be performed on Knopflerfish OSGi android projects but are actually applicable to other OSGI frameworks. There is no need for modification of the OSGi framework itself, we'll only update the projects KfServiceLib and KfBasicApp in the tool directory of the Knopflerfish distribution.

功能和限制

这是Android框架定制的第一级。这些变化将尚未有无关,与上下文或调用线程,但它们允许使用一组的Andr​​oid API类的有限像 android.util.Log

This is the first level of customization of the framework for android. These changes will yet have nothing to do with the context or calling thread but they allow the use of a limited set of android API classes like android.util.Log.

由于这些变化,包将能够使用Android的类在他们的原型和其执行情况。然而,他们将能够无相关的图形用户界面,内容提供者,和服务系统等,因为它们缺乏用于它的强制性引用

Thanks to these changes, bundles will be able to use android classes in their prototypes and in their implementation. Nevertheless, they will be capable of nothing related to graphical user interface, content providers, and system services and so on, because they lack the mandatory references for it.

变化Knopflerfish应用

由于他们是,在工具/安卓/ APK应用程序能够执行OSGi框架在Android上,但只有当包只调用Java类。这对属于Knopflerfish框架的一部分是什么自定义捆绑想要调用Android的API,但捆的情况?这里是做了框架,使包解决安卓类的变化。

As they are, the applications under tools/android/apk are able to execute the OSGi framework on android but only if the bundles are only calling java classes. That’s the case for the bundles that are part of the Knopflerfish framework but what of custom bundles wanting to call android API? Here are the changes to make in the framework to enable the bundles resolving android classes.

首先,Android包必须是架构软件包的一部分,使他们能够得到解决。这是OSGi财产的目的 org.osgi.framework.system.packages.extra

First, the android packages must be part of the framework packages so they can be resolved. This is the purpose of the OSGi property org.osgi.framework.system.packages.extra

设置属性的Andr​​oid包创建的框架之前导出列表中,您设置。 ,采取通知野生焦安卓* 似乎没有任何效果。我们有一个像下面来告诉每个包一个

Set the property to the list of android packages to export before creating the framework and you are set. Take notice that the wild char android.* seems to have no effect: we have to tell each package one by one like below.

要添加到 KfServiceLib 文件SRC /组织/ knopflerfish /安卓/服务/ KfApk.java

To add to KfServiceLib in file src/org/knopflerfish/android/service/KfApk.java

static final String ANDROID_FRAMEWORK_PACKAGES = (
            "android,"
            + "android.app,"
            + "android.content,"
            + "android.database,"
            + "android.database.sqlite,"
            + "android.graphics,"
            + "android.graphics.drawable,"
            + "android.graphics.glutils,"
            + "android.hardware,"
            + "android.location,"
            + "android.media,"
            + "android.net,"
            + "android.net.wifi,"
            + "android.opengl,"
            + "android.os,"
            + "android.provider,"
            + "android.sax,"
            + "android.speech.recognition,"
            + "android.telephony,"
            + "android.telephony.gsm,"
            + "android.text,"
            + "android.text.method,"
            + "android.text.style,"
            + "android.text.util,"
            + "android.util,"
            + "android.view,"
            + "android.view.animation,"
            + "android.webkit,"
            + "android.widget");

然后我们设置额外的软件包 KfApk.newFramework()

  config.put(Constants.FRAMEWORK_STORAGE, fwDir);

  // Export android packages so they can be referenced by bundles
  config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA,
    ANDROID_FRAMEWORK_PACKAGES);

备注​​的:如果可以的话,这是最好的方式用一个文件,而不是由code程序中设置了额外的配置

Remark: if you can, it is way better to set the extra configuration with a file rather than by code in the program.

导入Android包捆

即使Android包加入到由框架申报系统包,一包仍需进口他们解决,像任何其他导入的包。

Even if the android packages were added to the system packages declared by the framework, a bundle still has to import them to resolve, like any other imported package.

例如:

进口包装:org.osgi.framework,android.content,android.widget,   android.util

Import-Package: org.osgi.framework, android.content, android.widget, android.util

备注​​的:你可以使用该按钮«自动»的Knopflerfish Eclipse插件的自动更新导入像他们应该是

Remark: you can use the button « auto » of the Knopflerfish Eclipse plugin to automatically update the imports like they should be.

更多变化Knopflerfish应用

这些改变后,你应该能够运行起自己或访问方面的资源,活动包。那么整套的Andr​​oid API的类应充分提供给捆绑。但也有适用于捆绑编码来实现这方面的一些限制。我们需要的是在应用程序上下文的参考,所以我们要推它的框架!

After these changes, you should be able to run bundles starting activities on their own or accessing context’s resources. The whole set of android API classes should then be fully available to bundles. But there are some constraints applying to bundle coding to achieve this. All we need is the reference on the application’s Context so we are going to push it in the framework!

要加入到 org.knopflerfish.android.service.Knopflerfish.onStartCommand()

if (fw != null) {
  // Register the application's context as an OSGi service!
  BundleContext bundleContext = fw.getBundleContext();
  regContext = bundleContext.registerService(Context.class,
    getApplicationContext(), new Hashtable());

  sendMessage(Msg.STARTED, (Serializable) KfApk.getFrameworkProperties());
} else {
  // framework did not init/start
  sendMessage(Msg.NOT_STARTED);
  stopSelf();
  return;
}

我们正在通过应用程序的情况下,也只有这一个,因为它是将存在于应用程序的整个生命中唯一的语境。它将被立即设定为在应用程序启动,这意味着以后安装或启动系统。该软件包可以维持在这方面的一个有力的参考,它是好的。

We are passing the application’s context, and only this one, because it is the only Context that will exist for the entire life of the application. It will be set as soon as the application starts, meaning after install or system boot. The bundles can maintain a strong reference on this Context, it is fine.

如何捆绑使用上下文

一个包得到上下文的BundleContext 传递给它的激活因子:

A bundle gets the Context from the BundleContext passed to its activator:

static Context context;

public void start(BundleContext bc) throws Exception {
  ServiceReference<Context> ref = bc.getServiceReference(Context.class);
  context = bc.getService(ref);
}

作为包被在不同的线程比UI线程中运行,UI操作只能当UI线程上推执行。要做到这一点,明智的做法是,设计这样一个可重复使用的工具方法:

As a bundle is running in a different thread than the UI thread, UI operations can only be performed if "pushed" on the UI thread. To do so, it is wise to design a reusable utility method like this:

public static void runOnContext(Context context, Runnable runnable) {
    Handler handler = new Handler(context.getMainLooper());
    handler.post(runnable);
}

此方法应是从一个公用包的服务的一部分,因为它应当由许多不同的Andr​​oid束进行访问的方式相同。

This method should be part of a service from an utility bundle since it should be accessed by many different android bundles the same way.

例如,该包是显示你好,因为它启动:

For example, this bundle is showing "Hello" as it starts:

public void start(BundleContext bc) throws Exception {
  ServiceReference<Context> ref = bc.getServiceReference(Context.class);
  final Context context = bc.getService(ref);

  runOnContext(context, new Runnable() {
    public void run() {
      Toast.makeText(context, "Hello", Toast.LENGTH_LONG).show();
    }
  });
}

便宜的方法来使用像束应用程序

我指的是APK转换为OSGi包作为的捆绑APK 的简称。

  • 创建一个普通APK,多亏了Eclipse的Andr​​oid项目为例
  • 添加的参考图书馆的进入到项目的构建路径的为您的OSGi框架(在我的情况framework.jar)
  • 编辑捆绑清单文件 bundle.manifest 描述的包(见下面的例子)。这个文件是不是真正的APK的一部分,但在将用于自定义生成步骤
  • 在说你的应用程序包是 com.acme.helloworld (此值设置清单:在AndroidManifest.xml中包),你的OSGi bundle的Activator类的必须被放置在包 com.acme.helloworld 键,您必须设置捆绑-SymbolicName:COM。 acme.helloworld 在bundle清单。如果这些条件不具备,则将会导致 java.lang.NoClassDefFoundError的上运行。
  • Create a regular APK, thanks to Eclipse Android Project for example
  • Add a Reference Library entry to the project Build Path for your OSGi framework (in my case framework.jar)
  • Edit a bundle manifest file bundle.manifest describing the bundle (see example below). This file is not really part of the APK but will be used during custom build steps
  • Say your application package is com.acme.helloworld (this value is set with manifest:package in AndroidManifest.xml), your OSGI bundle's Activator class MUST be placed in the package com.acme.helloworld and you MUST set Bundle-SymbolicName: com.acme.helloworld in the bundle manifest. If any of these conditions is not met then will result in a java.lang.NoClassDefFoundError on runtime.

有关的提醒,你的包清单文件应该是这样的:

For reminder, your bundle manifest file should look like this:

Manifest-Version: 1.0
Bundle-Vendor: Acme
Bundle-Version: 1.0.0
Bundle-Name: HelloWorldBundle
Bundle-ManifestVersion: 2
Bundle-Activator: com.acme.helloworld.Activator
Bundle-Description: Hello World Bundle
Import-Package: org.osgi.framework
Bundle-SymbolicName: com.acme.helloworld
Bundle-RequiredExecutionEnvironment: OSGi/Minimum-1.0

  • 使用的安卓工具>导出未签名的Andr​​oid Package的
  • 复制 bundle.manifest 在生成的无符号的APK为 META-INF / MANIFEST.MF
  • 在使用任何证书,你要注册的APK。在这里,你有你的包APK准备
  • 安装的APK包像往常一样。安装时,必须以有解决的活动。如果没有这种活动不会解决和包将失败
  • 有OSGi框架加载和启动APK包(非常相同的APK文件)
    • Use Android Tools > Export Unsigned Android Package
    • Copy bundle.manifest in the generated unsigned APK as META-INF/MANIFEST.MF
    • Sign the APK using whatever certificate you want. Here you have your bundle APK ready
    • Install the bundle APK like usual. Installation is required in order to have the activities resolved. Without this the activity won't resolve and the bundle will fail
    • Have the OSGi framework load and start the bundle APK (the very same APK file)
    • 要开始从包APK活动,请使用以下code。

      To start the activity from the bundle APK, use the following code.

      // This is the application's context provided by the framework
      // Context ctx = ...
      
      Intent intent = new Intent();
      String pkgName = YourActivity.class.getPackage().getName();
      String clssName = YourActivity.class.getName();
      intent.setClassName(pkgName, clssName);
      
      // You may add the NEW_TASK flag
      intent.addFlag(Intent.FLAG_ACTIVITY_NEW_TASK);
      
      // Important: do not use startActivity(Context, Class) version because it will fail to resolve the activity
      ctx.startActivity(intent);
      

      登录

      初始

      在这一点上我的努力,Android的包:

      At this point of my efforts, android bundles:

      • 只要能打电话的Andr​​oid SDK类,因为他们并不需要的资源 或声明在AndroidManifest.xml中,
      • 可以访问应用程序的 android.content.Context ,它可以用来启动活动了OSGi框架中。
      • can call android SDK classes as long as they don't require resources or declaration in AndroidManifest.xml,
      • have access to the application's android.content.Context, which can be used to start activities out of the OSGi framework.

      捆绑不能:

      • 在请求的Andr​​oid权限,
      • 在构建布局的活动甚至没有启动它们,
      • 定义静态广播接收器,在的Andr​​oidManifest.xml 宣布,尽管受code实例化一个接收器应该就可以了。
      • request android permission,
      • build activities from layout not even start them at all,
      • define static broadcast receiver, declared in AndroidManifest.xml, though a receiver instantiated by code should be fine.

      这是因为我已经经历了这么远,我努力克服的局限性,我请求帮助的目标。

      That's for the limitations I have experienced so far that I am trying to overcome and the goal of my request for help.

      我所瞄准:

      • 在对内部资源的支持,特别是布局,
      • 能够通过XML构建,如果不能创建和启动内部活动,由code。

      什么是我迄今取得的成就,通过临床试验:

      What are my achievements so far, through trials:

      • 请认为既是一个OSGi包,并通过混合建设者,出口未签名的二进制文件和手动合并 bundle.manifest 进入清单的APK /安卓库的Andr​​oid项目。 MF签订的jarsigner 之前。结果是APK是由OSGi framwork加载并起的状态的解决的,但不能启动由于 java.lang.NoClassDefFoundError的我的激活器类,即使类是classes.dex的一部分,还有就是路径上没有明显的错误。使该项目成为一个OSGi包与Android的依赖获得进入激活而不是Android的资源在JAR。令人费解。
      • 验证所有的本指南的可以做部分中描述的功能。
      • Make an android project seen as both an OSGi bundle and an APK/android library by mixing the Builders, exporting unsigned binaries and manually merging bundle.manifest into the MANIFEST.MF before signing with jarsigner. The results are the APK is loaded by the OSGi framwork and gets up to the state resolved but is not able to start due to java.lang.NoClassDefFoundError on my activator class, even if the class is part of classes.dex and there is no apparent error on the path. Making the project be an OSGi bundle with android dependencies gets access to the activator but not to android resources in the JAR. Puzzling.
      • Validate all of the features described in the "can do" section of this guide.

      修改2013年9月3日

      我已经找到一种方法来启动搭载Android包拥有的活动。请参见相应的章节。

      I have found a way to start activities owned by android bundles. See the corresponding chapter.

      修改2013年9月10日:通用OSGi框架容器

      几天后,我做了一般运行任何OSGi框架我想要的Knopflerfish程序。举例来说,我是presently运行Knopflerfish或菲利克斯以同样的方式。仍有需要一种特定的框架结构。

      After several days, I have made the Knopflerfish programs generic to run whatever OSGi framework I want. For instance, I am presently running Knopflerfish or Felix the same way. There is still a need for a specific framework configuration.

      这意味着该主题不再Knopflerfish只,即使按Knopflerfish发行所需要的程序。

      That means the topic is no longer Knopflerfish only, even if the needed programs were issued by Knopflerfish.

      2013年9月27日:现状和总体框架比较

      我已经把这个项目搁置了一段时间由于优先级的改变。不过,我评估了以下解决方案至今:

      I have to put this project aside for some time due to a change in priority. However I evaluated the following solutions so far:

      • Knopflerfish OSGi的[开放源代码]
      • 菲利克斯和FelixDroid [开源]
      • ProSyst MBS SDK(春分为主,商业用途)

      要概括起来讲,没有人有一个整洁的优势,当涉及到图形用户界面支持:他们都可以在Android的方式处理资产或资源(字符串,布局,图像),但你仍然可以处理它们为OSGi资源与OSGi的API,但你将无法使用他们在机器人像往常一样。

      To sum it up, none of them has a neat advantage when it comes to GUI support: none of them can handle assets or resources (strings, layouts, images) in the android way, but you can still handle them as OSGi resource with the OSGi API but you won't be able to use them in android as usual.

      我个人喜欢Knopflerfish的管理控制台servlet的,但它的图形用户界面支持金额不了了之。费利克斯+ FelixDroid有一个很好的平衡了免费OSGi的解决方案,而MBS SDK支持不同VM目标广泛号码和定义可能适合专业开发人员味道更意图基于应用程序框架。

      I personally like the Knopflerfish's administration console servlet but its GUI support amounts to nothing. Felix + FelixDroid has a good balance for a free OSGi solution whereas mBS SDK supports a wide number of different VM targets and defines an intent based application framework that might fit professional developers taste more.

      鉴于Knopflerfish和Felix使用几乎相同的方式,MBS SDK是在很多方面有很大不同。 Knopflerfish和Felix是可交换:我写了一个容器程序,其中选择OSGi框架是选择不同的手只是迟早的问题做出JAR依赖

      Whereas Knopflerfish and Felix are used almost the same way, mBS SDK is very different in many aspects. Knopflerfish and Felix are exchangeable: I have written a container program where choosing the OSGi framework is only a matter of selecting a different hand made JAR dependency!

      当涉及到图形用户界面,Knopflerfish提供有关什么。你需要去通过我的指导方针,以拥有更多的支持。在FelixDroid主要的想法是好的,它实际上是类似的东西在MBS SDK实现的,但它是一个有点浪费不具备实现作为一个包。再多说一句,MBS SDK已经通过定义特定意图启动了一个OSGi应用程序框架做了件事很好。两者都整合意见的主要活动大致相同的方式。

      When it comes to GUI, Knopflerfish provides about nothing. You'll need to go through my guidelines in order to have a bit more support. The main idea in FelixDroid is good, it is actually something similar implemented in mBS SDK, but it is a bit of a waste to not have the implementation as a bundle. More to say, mBS SDK has done the thing more nicely by defining an OSGi applications framework started by specific intents. Both are integrating views in the main activity about the same way.

      在MBS SDK另一个惊人的区别是你不需要添加Android框架的依赖性,也没有增加进口,包装指令,让他们在你的包。它是依靠Knopflerfish或菲利克斯一段时间后肯定是令人不安的。此外,它完全集成在Eclipse和供应开发了许多方便的任务:PC为目标OSGi框架监测(KF和费利克斯只提供对目标管理控制台)和快速部署。凹坑基本上是不是免费的,容器的应用是几乎不可能定制

      Another stunning difference in mBS SDK is you don't need to add the android framework dependencies nor add Import-Package directives for them in your bundles. It is certainly disturbing after relying on Knopflerfish or Felix for a while. Also it is fully integrated in Eclipse and supply the developer with many handy tasks: PC to target OSGi framework monitoring (Kf and Felix provide only a on-target administration console) and fast deployment. The pits are essentially that is is not free and that the container application is nearly impossible to customize.

      推荐答案

      我已经由纯粹的运气发现了一些有前途的开源(Apache许可证2)框架可能会感兴趣。这就是所谓的 DEMUX框架。随意评估该解决方案。我不是我自己,而是通过功能和源$ C ​​$ C浏览,让我觉得它有一个很好的潜力和整洁的一体化。关于GUI支持,它采用类似于FelixDroid的方法。它可能成为一个开源替代品Prosyst MBS SDK。

      I have found by pure luck some promising Open Source (Apache License 2) framework that might be of interest. It's called DEMUX Framework . Feel free to evaluate this solution. I haven't myself but browsing through the features and source code let me think it has a good potential and neat integration. Regarding the GUI support, it uses an approach similar to FelixDroid. It could become an Open Source alternative to Prosyst mBS SDK.

      这是怎么它的设计者定义的框架:

      This is how its designer defines the framework:

      DEMUX框架很容易让Java开发人员构建   并从单一的code应用程序桌面,Web的移动设备   基础。它提供了模块化的应用架构基于OSGi,   这可以很容易地构建健壮的,可扩展的应用程序。

      DEMUX Framework makes it easy for Java developers to build applications for desktop, web and mobile devices from single code base. It provides modular applications architecture based on OSGI, which makes it easy to build robust and extensible applications.

      但Android是在这个阶段唯一支持的移动操作系统,我祝他好运了另外两个(我曾在过去的一些痛苦的经历对这个问题)

      However Android is the only mobile OS supported at this stage and I wish him good luck for the other two (I had some painful experiences in the past on this subject)

      这篇关于为OSGi包完全支持Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆