`
mintelong
  • 浏览: 396200 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

利用Eclipse和NDK建立一个简单service

阅读更多
NDK是Google提供的一套开发支持Native代码的应用程序的工具。因为Android用了自己改写的C库(Bionic),并应用自己的compiler和linker,所以如果想用通用的toolchain编译Android应用中C/C++代码就比较麻烦。之前的方法是,可以把自己的代码整合到整个Android系统中,利用Android Build System的编译工具进行编译(具体例子可以参看<android source>/development/samples/下的PlatformLibrary和SimpleJNI两个例子)。但是缺点是要建立整个的Build的环境,第一次Build所有的代码时间很长。
NDK则提供了一个相对简单Build System。只要按它的要求提供应用和Native代码位置及要编译的模块等基本信息,然后用它提供的工具就可以很方便的生成Shared Librare,并自动将其拷贝到SDK应用开发的环境下方便生成apk。具体的介绍在<android NDK>/docs/下。
以下是我应用NDK做的一个小实验。其实前面基本上就是在Eclipse下建立一个Service应用,只是在Service中用到的share library是用NDK生成的。与NDK相关部分用红色标注,在工程中加入*.mk,jni等只是为了方便编辑。

实验环境:
Ubuntu, SDK 1.5r2, NDK 1.5r1, Eclipse3.4 (ADT plugin)

具体步骤记录如下:
1.在Eclipse下新建Android-Project项目MyServer,Package为ndk.sample.myservice;
2.在MyServer/src/ndk.sample.myservice下:
a)添加aidl文件:IMyService.aidl,之后在gen/sample.ndk.myserver下会自动生成IMyService.java;

# package ndk.sample.myservice;
# interface IMyService {
# String getGreetings(in String toName);
# }


b)实现MyService;
   2. package ndk.sample.myservice;
   3. import android.app.Service;
   4. import android.content.Intent;
   5. import android.os.IBinder;
   6. import android.util.Log;
   7. public class MyService extends Service {
   8. private final IMyService.Stub binder = new IMyService.Stub() {
   9.   public String getGreetings(String toName) {
  10.    return get_greetings(toName);
  11.   }
  12. };
  13.

  14. @Override
  15. public void onCreate() {
  16.   Log.v("MyService", "Lifecycle - onCreate");
  17. }
  18.

  19. @Override
  20. public void onDestroy() {
  21.   Log.v("MyService", "Lifecycle - onDestroy");
  22. }
  23.

  24. @Override
  25. public void onStart(Intent intent, int startId) {
  26.   Log.v("MyService", "Lifecycle - onStart: id = " + Integer.toString(startId));
  27. }
  28.

  29. @Override
  30. public IBinder onBind(Intent intent) {
  31.   Log.v("MyService", "Lifecycle - onBind");
  32.   return this.binder;
  33. }
  34. @Override
  35. public void onRebind(Intent intent) {
  36.   Log.v("MyService", "Lifecycle - onRebind");
  37. }
  38.

  39. @Override
  40. public boolean onUnbind(Intent intent) {
  41.   Log.v("MyService", "Lifecycle - onUnbind");
  42.   return false;
  43. }
  44.

  45. static {
  46.   System.loadLibrary("mynativecodes");
  47. }
  48.

  49. public native String get_greetings(String toName);
  50. }


c)实现TestClient;

  
2. package ndk.sample.myservice;
   3. import android.app.Activity;
   4. import android.content.ComponentName;
   5. import android.content.Intent;
   6. import android.content.ServiceConnection;
   7. import android.os.Bundle;
   8. import android.os.IBinder;
   9. import android.os.RemoteException;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.widget.Button;
  13. import android.widget.EditText;
  14. import android.widget.TextView;
  15. public class TestClient extends Activity {
  16.     private TextView tvGreetings;
  17.     private EditText etName;
  18.     private IMyService service;
  19.    
  20.     private ServiceConnection connection = new ServiceConnection () {
  21.      @Override
  22.      public void onServiceConnected(ComponentName className, IBinder iservice) {
  23.       service = IMyService.Stub.asInterface(iservice);
  24.      }
  25.      
  26.      @Override
  27.      public void onServiceDisconnected(ComponentName className) {
  28.       service = null;
  29.      }
  30.     };
  31.    
  32.     @Override
  33.     public void onCreate(Bundle savedInstanceState) {
  34.         super.onCreate(savedInstanceState);
  35.         setContentView(R.layout.main);
  36.         
  37.         tvGreetings = (TextView)findViewById(R.id.tvGreetings);
  38.         etName = (EditText)findViewById(R.id.etName);
  39.         
  40.         Button btnHello = (Button)findViewById(R.id.btnHello);
  41.         btnHello.setOnClickListener(new View.OnClickListener () {
  42.          @Override
  43.          public void onClick(View view) {
  44.           String toName = etName.getText().toString();
  45.           try {
  46.            String greetings = service.getGreetings(toName);
  47.            tvGreetings.setText(greetings);
  48.            etName.setText("");
  49.           }
  50.           catch (RemoteException e) {
  51.            Log.e("TestClient", "error", e);
  52.           }
  53.          }
  54.         });
  55.     }
  56.    
  57.     @Override
  58.     public void onStart() {
  59.      super.onStart();
  60.      
  61.      boolean rc = bindService(
  62.        new Intent(IMyService.class.getName()),
  63.        connection, BIND_AUTO_CREATE);
  64.      if (rc == false)
  65.       Log.v("TestClient", "Fail to bindService");
  66.     }
  67.    
  68.     @Override
  69.     public void onStop() {
  70.      super.onStop();
  71.      
  72.      unbindService(connection);
  73.     }
  74. }


d)修改AndroidManifest.xml,添加service

# <?xml version="1.0" encoding="utf-8"?>
# <manifest xmlns:android="http://schemas.android.com/apk/res/android"
#       package="ndk.sample.myservice"
#       android:versionCode="1"
#       android:versionName="1.0">
#     <application android:icon="@drawable/icon" android:label="@string/app_name">
#         <activity android:name=".TestClient"
#                   android:label="@string/app_name">
#             <intent-filter>
#                 <action android:name="android.intent.action.MAIN" />
#                 <category android:name="android.intent.category.LAUNCHER" />
#             </intent-filter>
#         </activity>
#         <service android:name=".MyService">
#          <intent-filter>
#           <action android:name="ndk.sample.myservice.IMyService" />
#          </intent-filter>>
#         </service>>
#     </application>
#     <uses-sdk android:minSdkVersion="3" />
# </manifest> 


e)添加Application.mk文件

  1. APP_PROJECT_PATH := $(call my-dir)
   2. APP_MODULES := mynativecodes


3.在MyService下添加目录jni:
a)从Terminal:
$ cd MyServer/jni
$ javah -jni -classpath ../bin ndk.sample.myservice.MyService
自动生成头文件ndk_sample_myservice_MyService.h

b)在MyServer/jni下添加mynative.c,实现

  
2. #include "ndk_sample_myservice_MyService.h"
   3. #include <stdio.h>
   4. #include <string.h>
   5. JNIEXPORT jstring JNICALL Java_ndk_sample_myservice_MyService_get_1greetings
   6.   (JNIEnv *env, jobject obj, jstring name)
   7. {
   8. // fixed buffer size for test
   9. char buf[128];
  10. const jbyte *str;
  11. str = (*env)->GetStringUTFChars(env, name, NULL);
  12. if (str == NULL) {
  13.   return NULL;
  14. }
  15. if (strlen (str) == 0)
  16.   sprintf (buf, "Who are you?");
  17. else
  18.   sprintf (buf, "Hello, %s!!!", str);
  19. (*env)->ReleaseStringUTFChars(env, name, str);
  20. return (*env)->NewStringUTF(env, buf);
  21. }


c)在MyServer/jni下添加Android.mk

# LOCAL_PATH := $(call my-dir)
# include $(CLEAR_VARS)
# LOCAL_MODULE := mynativecodes
# LOCAL_SRC_FILES := mynative.c
# include $(BUILD_SHARED_LIBRARY)


4.在Terminal下,进入NDK目录,建立指向应用和share library的链接(可以不把自己的代码放在NDK的目录下,但必须在NDK中加入指向存放Application.mk和Android.mk的路径的链接)
$ cd <androi ndk>
$ cd sources
$ ln -s <my service dir>/ myservice
$ cd ../apps
$ ln -s <my service dir>/jni/ mynativecodes
$ cd ../
$ make APP=myservice V=1
APP部分指明要编译的应用名(路径名),必须有。V=1指定显示编译命令,可以没有。编译成功后,可以在libs\armeabi下生成了libmynativecodes.so,Eclipse环境中也可以看到。
5.最后按正常的方法生成MyService的apk即可。 

分享到:
评论

相关推荐

    Eclipse配置NDK环境

    在Android应用开发中,Eclipse作为一个老牌的集成开发环境(IDE),虽然已经逐渐被Android Studio所取代,但在某些开发者的圈子里仍然有一定的使用群体。NDK(Native Development Kit)是Google提供的一个开发包,允许...

    com.android.ide.eclipse.ndk_23.0.2.1259578.jar

    android adt自带eclipse无法设置ndk路径,需要下载com.android.ide.eclipse.ndk_23.0.2.1259578.jar文件,然后复制到sdk 只带的eclipse目录的“plugins”下面,如我的复制到"D:\Android\adt-bundle-windows-x86_64-...

    Android开发eclipse NDK插件

    android开发有时需要开发c/c++插件,这就需要用到NDK(Native Development Kit),如果eclipse中没有配置NDK的选项则需要此...解压后对应放入eclipse目录下的features和plugins文件夹重启eclipse就可以看到NDK的选项了。

    非常强大的eclipse中android ndk开发环境的配置说明

    通过以上步骤,您可以在Eclipse中成功配置出Android NDK开发环境,实现C/C++代码的自动编译和JNI头文件的自动生成,极大地提高了开发效率和便利性。无论是对于初学者还是有经验的开发者来说,这一套配置都将带来巨大...

    解决eclipse无NDK选项设置问题.zip

    本教程主要针对一个常见问题:在Eclipse中找不到NDK(Native Development Kit)的设置选项,提供解决方案。 NDK是Google提供的一个工具集,它允许开发者用C和C++编写原生代码,以提高Android应用的性能和效率,特别...

    eclipse集成 android ndk(doc)(文档)

    Eclipse集成Android NDK说明 1 2 为什么要用NDK? 2 3 为什么要集成? 2 4 怎样操作? 2 4.1 预备条件 2 4.1.1 Cygwin 2 4.1.2 Eclipse 2 4.1.3 Eclipse CDT 3 4.1.4 Android SDK 3 4.1.5 Android NDK 3 ...

    Eclipse下NDK开发参考

    5. **验证配置**:创建一个简单的测试项目,如使用 C/C++ 代码实现一个基本功能,并尝试构建和运行这个项目以确认配置是否正确无误。 ### 使用 NDK 构建和调试 #### 构建流程 1. **编辑 Makefile**:在项目根目录...

    com.android.ide.eclipse.ndk_23

    Android Native Development Kit (NDK) 是Google为Android开发者提供的一款工具集,允许开发人员使用C和C++原生代码编写部分或全部应用。在某些情况下,NDK可以提高性能,尤其是处理密集型计算或者利用硬件加速功能...

    ECLIPSE下的androidndk开发

    - **Eclipse CDT**:C/C++ Development Tooling,是Eclipse中的一个插件,用于支持C/C++的开发和调试。 - **Android SDK**:包含了构建Android应用所需的工具和库。 - **Android NDK**:下载并安装NDK,它包含了一...

    解决eclipse无NDK选项设置问题

    解决eclipse无NDK选项设置问题,复制下载文件到eclipse目录的“plugins”下面。如我的复制到"\eclipse\plugins\com.android.ide.eclipse.ndk_23.0.2.1259578.jar"。

    Eclipse配置NDK开发环境

    NDK是Google提供的一个工具集,允许开发者在Android应用中使用C和C++代码,以实现高性能或利用特定硬件的功能。 配置Eclipse以进行NDK开发主要包括以下几个步骤: 1. **安装ADT插件**:首先,确保你已经安装了...

    解决eclipse无NDK选项设置问题 com.android.ide.eclipse.ndk_23.0.2.1259578.jar

    解决eclipse无NDK选项设置问题。复制到eclipse目录的“plugins”下面。如我的复制到"\eclipse\plugins\com.android.ide.eclipse.ndk_23.0.2.1259578.jar"

    解决Eclipse的ADT没有NDK选项的问题

    标题中的问题“解决Eclipse的ADT没有NDK选项的问题”是针对Android开发环境中一个常见的技术挑战。在Android开发中,NDK(Native Development Kit)是Google提供的一个工具集,用于在C或C++中编写部分应用程序,以...

    adt bundle自带eclipse的NDK配置

    但是adt bundle中自带的eclipse没有NDK选项,原因是缺少一个包: com.android.ide.eclipse.ndk_23.0.2.1259578.jar 将这个包放在eclipse的plugins文件夹下,重启eclipse,就可以看到NDK的选项了。

    eclipse中ndk 自动编译配置

    而在Eclipse集成开发环境中进行NDK的配置与编译,则是一个重要的步骤。本文将详细介绍如何在Eclipse中配置NDK以实现SO库的自动编译。 #### 二、环境准备 1. **Eclipse IDE**:确保已经安装了Eclipse for Java ...

    eclipse adt ndk插件

    eclipse adt ndk插件

    com.android.ide.eclipse.ndk_23.0.4

    解决eclipse无NDK选项设置问题。复制到eclipse目录的“plugins”下面。如我的复制到"\eclipse\plugins\com.android.ide.eclipse.ndk_23.0.4.1468518.jar" 然后重启Eclipse

Global site tag (gtag.js) - Google Analytics