开始对嵌入的Android Knopflerfish一个Bundle不起作用(Starting a

2019-10-30 02:10发布

我嵌入Knopflerfish框架变成一个Android应用程序启动和停止动态捆绑。

我跟着这个教程,下载framework.jar弗罗姆这个链接,并在我的Eclipse项目把它添加到我的类路径。

另外,下面是活动类,它启动框架,并且开始一个束:

package com.example.knopflerfish_android;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Map;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;

import org.knopflerfish.framework.FrameworkFactoryImpl;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
import org.osgi.service.startlevel.StartLevel;




public class MainActivity extends Activity {

private static final String TAG = "Zaid Log";
private Framework mFramework;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        System.out.println("here!");

        Map<String, String> fwprops = new Hashtable<String, String>(); //CHANGED

        // add any framework properties to fwprops
        fwprops.put("org.osgi.framework.storage", "sdcard/fwdir");

        FrameworkFactory ff = new FrameworkFactoryImpl();
        mFramework = ff.newFramework(fwprops);



        try {

            mFramework.init(); //STUCK HERE!!


        } catch (BundleException be) {
            // framework initialization failed

            Log.d(TAG, be.getStackTrace().toString());
            Log.d(TAG,"failed to initialize Framework");
        }



        setInitlevel(1);


        installBundle("Bundle_AndroidAPI_1.0.0.201308160327.jar");
        startBundle("Bundle_AndroidAPI_1.0.0.201308160327.jar");
        // install/start other bundles...


        setStartLevel(10);

        try {
            mFramework.start();
        } catch (BundleException be) {
            Log.e(TAG, be.toString());
            // framework start failed
        }

        Log.d(TAG, "OSGi framework running, state: " + mFramework.getState());


      /*  helloServiceReference= context.getServiceReference(HelloService.class.getName());
        HelloService helloService =(HelloService)context.getService(helloServiceReference);
        System.out.println(helloService.sayHello());*/
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }


    private void startBundle(String bundle) {
        Log.d(TAG, "starting bundle " + bundle);
        InputStream bs;
        try {
            bs = getAssets().open("bundles/" + bundle);
        } catch (IOException e) {
            Log.e(TAG, e.toString());
            return;
        }

        long bid = -1;
        org.osgi.framework.Bundle[] bl = mFramework.getBundleContext().getBundles();
        for (int i = 0; bl != null && i < bl.length; i++) {
            if (bundle.equals(bl[i].getLocation())) {
                bid = bl[i].getBundleId();
            }
        }

        org.osgi.framework.Bundle b = mFramework.getBundleContext().getBundle(bid);
        if (b == null) {
            Log.e(TAG, "can't start bundle " + bundle);

            return;
        }

        try {
            b.start(org.osgi.framework.Bundle.START_ACTIVATION_POLICY);
            Log.d(TAG, "bundle " + b.getSymbolicName() + "/" + b.getBundleId() + "/"
                    + b + " started");
            Toast.makeText(getApplicationContext(),"bundle " + b.getSymbolicName() + "/" + b.getBundleId() + "/"
                    + b + " started" , Toast.LENGTH_SHORT).show();


        } catch (BundleException be) {
            Log.e(TAG, be.toString());
        }

        try {
            bs.close();
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        }
    }

    private void installBundle(String bundle) {
        Log.d(TAG, "installing bundle " + bundle);
        Toast.makeText(getApplicationContext(), "installing bundle", Toast.LENGTH_SHORT).show();

        InputStream bs;
        try {
            bs = getAssets().open("bundles/" + bundle);
        } catch (IOException e) {
            Log.e(TAG, e.toString());
            return;
        }

        try {
            mFramework.getBundleContext().installBundle(bundle, bs);
            Log.d(TAG, "bundle " + bundle + " installed");
            Toast.makeText(getApplicationContext(), "bundle " + bundle + " installed", Toast.LENGTH_SHORT).show();
        } catch (BundleException be) {
            Log.e(TAG, be.toString());
        }

        try {
            bs.close();
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        }
    }

    private void setStartLevel(int startLevel) {
        ServiceReference sr = mFramework.getBundleContext()
            .getServiceReference(StartLevel.class.getName());
        if (sr != null) {
            StartLevel ss =
                (StartLevel)mFramework.getBundleContext().getService(sr);
            ss.setStartLevel(startLevel);
            mFramework.getBundleContext().ungetService(sr);
        } else {
            Log.e(TAG, "No start level service " + startLevel);
        }
    }

    private void setInitlevel(int level) {
        ServiceReference sr = mFramework.getBundleContext()
            .getServiceReference(StartLevel.class.getName());
        if (sr != null) {
            StartLevel ss =
                (StartLevel)mFramework.getBundleContext().getService(sr);
            ss.setInitialBundleStartLevel(level);
            mFramework.getBundleContext().ungetService(sr);
            Log.d(TAG, "initlevel " + level + " set");
        } else {
            Log.e(TAG, "No start level service " + level);
        }
    }


}

正如我说前面的问题 ,根据@ldx 这个帖子,“我在Knopflerfish提交了更好的Android / Dalvik的支持的补丁已经被合并,以便修补和重新编译KF不应该是必要再”

因此,我没有添加任何假设我的代码就足够了,因为它是现在。

当我运行Android应用程序,我没有得到任何错误,相反,我得到我的logcat说我束安装并启动了积极的信息。 见下面(我忽略了前两行)我的日志:

08-15 23:32:08.381: E/Trace(22044): error opening trace file: No such file or directory (2)
08-15 23:32:08.381: E/Trace(22044): error opening trace file: No such file or directory (2)
08-15 23:32:09.441: I/System.out(22044): here!
08-15 23:32:10.320: D/dalvikvm(22044): GC_CONCURRENT freed 172K, 10% free 2695K/2984K, paused 73ms+85ms, total 236ms
08-15 23:32:10.720: D/dalvikvm(22044): GC_CONCURRENT freed 324K, 14% free 2816K/3260K, paused 73ms+85ms, total 214ms
08-15 23:32:10.762: D/Zaid Log(22044): initlevel 1 set
08-15 23:32:10.762: D/Zaid Log(22044): installing bundle Bundle_AndroidAPI_1.0.0.201308160327.jar
08-15 23:32:11.060: D/Zaid Log(22044): bundle Bundle_AndroidAPI_1.0.0.201308160327.jar installed
08-15 23:32:11.080: D/Zaid Log(22044): starting bundle Bundle_AndroidAPI_1.0.0.201308160327.jar
08-15 23:32:11.090: D/Zaid Log(22044): bundle Bundle_AndroidAPI/4/BundleImpl[id=4] started
08-15 23:32:11.140: D/Zaid Log(22044): OSGi framework running, state: 32
08-15 23:32:12.012: D/gralloc_goldfish(22044): Emulator without GPU emulation detected.
08-15 23:32:52.941: I/Choreographer(22044): Skipped 47 frames!  The application may be doing too much work on its main thread.

然而,我的包并没有真正启动。 在包的启动方法的消息就已经显示了在logcat的,如果我的包才真正开始。 下面是我的包开始的方法:

public void start(BundleContext bundleContext) throws Exception {
    Activator.context = bundleContext;


    System.out.println("Hello World. I am the OSGI_Android_Bundle!");


}

请注意,我的束dexified,但是却并不在我的应用程序启动。 我哪里做错了?

更新1:我想我应该交换架构的起点与纤维束的起点。 本教程的作者首先启动捆绑,但我想改变这种状况,因为它是有道理的,首先启动的框架,所以我更新的代码有以下几点:

setInitlevel(1);


// install/start other bundles...


setStartLevel(10);

try {
    mFramework.start();
} catch (BundleException be) {
    Log.e(TAG, be.toString());
    // framework start failed
}

Log.d(TAG, "OSGi framework running, state: " + mFramework.getState());


installBundle("Bundle-Test_1.0.0.201308160536.jar");
startBundle("Bundle-Test_1.0.0.201308160536.jar");

现在,日志不显示我,我的包像以前开始,而是它告诉我,执行环境不支持。 请参阅下面的更新logcat的:

08-16 01:43:06.821: I/System.out(22737): here!
08-16 01:43:08.080: D/dalvikvm(22737): GC_CONCURRENT freed 191K, 11% free 2656K/2968K, paused 35ms+18ms, total 155ms
08-16 01:43:09.010: D/dalvikvm(22737): GC_CONCURRENT freed 276K, 13% free 2806K/3200K, paused 25ms+15ms, total 110ms
08-16 01:43:09.238: D/Zaid Log(22737): initlevel 1 set
08-16 01:43:09.300: D/Zaid Log(22737): OSGi framework running, state: 32
08-16 01:43:09.300: D/Zaid Log(22737): installing bundle Bundle-Test_1.0.0.201308160536.jar
08-16 01:43:09.530: D/Zaid Log(22737): bundle Bundle-Test_1.0.0.201308160536.jar installed
08-16 01:43:09.540: D/Zaid Log(22737): starting bundle Bundle-Test_1.0.0.201308160536.jar
08-16 01:43:09.550: E/Zaid Log(22737): org.osgi.framework.BundleException: Bundle#5, unable to resolve: Execution environment 'J2SE-1.5' is not supported
08-16 01:43:10.740: D/gralloc_goldfish(22737): Emulator without GPU emulation detected.

更新2:我删除了从我以下@以下Neil的回答包Manifest这条线,

Bundle-RequiredExecutionEnvironment: J2SE-1.5

但是这导致了以下错误:

 org.osgi.framework.BundleException: Bundle#6 start failed

也许,我不该换首发的框架和开始包的顺序。 下面是我的更新logcat的。

08-16 17:02:33.855: E/Trace(28805): error opening trace file: No such file or directory (2)
08-16 17:02:35.111: I/System.out(28805): here!
08-16 17:02:35.591: D/dalvikvm(28805): GC_CONCURRENT freed 199K, 11% free 2679K/2996K, paused 76ms+93ms, total 246ms
08-16 17:02:36.153: D/dalvikvm(28805): GC_CONCURRENT freed 268K, 13% free 2814K/3200K, paused 77ms+141ms, total 297ms
08-16 17:02:36.451: D/Zaid Log(28805): initlevel 1 set
08-16 17:02:36.531: D/Zaid Log(28805): OSGi framework running, state: 32
08-16 17:02:36.531: D/Zaid Log(28805): installing bundle Bundle-Test_1.0.0.201308161323.jar
08-16 17:02:36.611: D/Zaid Log(28805): bundle Bundle-Test_1.0.0.201308161323.jar installed
08-16 17:02:36.631: D/Zaid Log(28805): starting bundle Bundle-Test_1.0.0.201308161323.jar
08-16 17:02:36.646: E/Zaid Log(28805): org.osgi.framework.BundleException: Bundle#6 start failed
08-16 17:02:36.646: E/Zaid Log(28805): More:Bundle#6 start failed
08-16 17:02:36.681: W/System.err(28805): org.osgi.framework.BundleException: Bundle#6 start failed
08-16 17:02:36.681: W/System.err(28805):    at org.knopflerfish.framework.BundleImpl.start0(BundleImpl.java:421)
08-16 17:02:36.681: W/System.err(28805):    at org.knopflerfish.framework.BundleThread.run(BundleThread.java:145)
08-16 17:02:36.681: W/System.err(28805): Caused by: java.lang.ClassNotFoundException: bundle_test.Activator
08-16 17:02:36.681: W/System.err(28805):    at org.knopflerfish.framework.BundleClassLoader.findClass(BundleClassLoader.java:218)
08-16 17:02:36.681: W/System.err(28805):    at org.knopflerfish.framework.BundleClassLoader.loadClass(BundleClassLoader.java:347)
08-16 17:02:36.681: W/System.err(28805):    at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
08-16 17:02:36.694: W/System.err(28805):    at org.knopflerfish.framework.BundleImpl.start0(BundleImpl.java:382)
08-16 17:02:36.694: W/System.err(28805):    ... 1 more
08-16 17:02:37.282: I/Choreographer(28805): Skipped 34 frames!  The application may be doing too much work on its main thread.
08-16 17:02:37.551: D/gralloc_goldfish(28805): Emulator without GPU emulation detected.

Answer 1:

我只解决你的问题,更新的错误,因为它似乎第一个问题是固定的(请确认)。

该错误是指一个包包括以下要求:

Bundle-RequiredExecutionEnvironment: J2SE-1.5

换句话说,束称,它需要标准的Java 5或更高。 这就是所谓的执行环境或EE。 通常情况下,OSGi框架检测什么样的Java运行时,你都推出了它,并将其发布了一组EE中以匹配。 例如,如果你在标准的Java运行5,框架发布评为电气工程师J2SE-1.5J2SE-1.4等所有的方式回到JRE-1.0 ,因为Java 5的是与所有这些版本的向后兼容。 但是,如果你有断言捆Bundle-RequiredExecutionEnvironment: JavaSE-1.6 ,并尝试在Java 5上运行它,那么它将无法化解。

现在,你想在Android上,这是不标准的Java运行。 虽然类似于标准的Java,标准JRE的API的许多地方已被删除。 因此,需要标准的Java 5捆不应该解决在Android,因为它可能会试图调用没有在该平台上存在的API。

也许为你做最简单的事情是去掉Bundle-RequiredExecutionEnvironment从没有解决丛标头。 这将允许安装它并解决,但当然以后可能会与运行时错误失败,如果它确实需要调用从标准JRE不存在于Android的方法。



文章来源: Starting a Bundle on Knopflerfish embedded into Android doesn't work