- 浏览: 834863 次
- 性别:
- 来自: 哈尔滨
-
文章分类
最新评论
-
doloveme:
$sudo cp MONACO_Linux.ttf /usr/ ...
terminator 的配置 -
腾讯rep:
lowser
RSA加密算法c++简单实现 -
csuhanyong:
好YD啊,好YD
一图流:机械键盘各轴区别 -
doloveme:
1。其中:extman ,extmail下载http://ww ...
Ubuntu下安装postfix+extmail邮件服务器 -
doloveme:
repo sync出现“fatal: '../platform ...
Android 编译环境配置搭建(Ubuntu 12.04)及环境导致编译错误QA
一、 Android Service 介绍
Android 的 Service 分为两种: Android Service 和 Native Service 。
Android Service :又称为 Java Service ,是实现在框架层( framework )里的 Server 。 Android Service 以 Java 编写。
Native Service :又称为 System Service ,是实现在 Runtime 层里的 Server 。
以 MediaPlayer 为例,从下图我们可以得出两种服务的关系:
接下来要讨论的 Service 是 Native Service ,与应用程序设计上所讨论的 Service ( android.app.Service )不同。
二、为什么要写底层的核心服务呢?
( 1 ) 因为底层核心服务是 Android 框架里最接近 Linux/Driver 的部分。为了充分发挥硬件设备的差异化特性,核心服务是让上层 Java 应用程序来使用 Driver/HW Device 特色的重要管道。
( 2 ) 在开机过程中,就可以启动核心服务 ( 例如汉字输入法服务等 ) ,让众多应用程序来共享之。
( 3 ) 由于共享,所以能有效降低 Java 应用程序的大小 (Size) 。
三、如何实现一个核心服务呢 ?
要点如下:
( 1 )核心服务通常在独立的进程 (Process) 里执行。
( 2 )必须提供 IBinder 接口,让应用程序可以进行跨进程的绑定 (Binding) 和呼叫。
( 3 )因为共享,所以必须确保多线裎安全 (Thread-safe) 。
( 4 )以 C++ 类别定义,诞生其对象,透过 SM 之协助,将该对象参考值传给 IServiceManager::addService() 函数,就加入到 Binder Driver 里了。
( 5 )应用程序可透过 SM 之协助而远距绑定该核心服务,此时 SM 会回传 IBinder 接口给应用程序。
( 6 )应用程序可透过 IBinder::transact() 函数来与核心服务互传数据。
四、 Server 实现实践
下面以一个小例子来说明具体实现一个 Server 的步骤。此实例功能为简单的整数加法 (Add) 运算,我们将其命名AddService 。
Step-1 :以 C++ 撰写 AddService 类别,其完整程序代码为:
AddService.h 文件:
#ifndef ANDROID_GUILH_ADD_SERVICE_H #define ANDROID_GUILH_ADD_SERVICE_H #include <utils.h> #include <utils/RefBase.h> #include <utils/IInterface.h> #include <utils/Parcel.h> namespace android { class AddService : public BBinder { mutable Mutex mLock; int32_t mNextConnId; public: static int instantiate(); AddService(); virtual ~AddService(); virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t); }; } #endif AddService.cpp 文件: #include "AddService.h" #include <utils/IServiceManager.h> #include <utils/IPCThreadState.h> namespace android { static struct sigaction oldact; static pthread_key_t sigbuskey; int AddService::instantiate() { LOGE("AddService instantiate"); int r = defaultServiceManager()->addService( String16("guilh.add"), new AddService()); LOGE("AddService r = %d/n", r); return r; } AddService::AddService() { LOGV("AddService created"); mNextConnId = 1; pthread_key_create(&sigbuskey, NULL); } AddService::~AddService() { pthread_key_delete(sigbuskey); LOGV("AddService destroyed"); } status_t AddService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ switch(code) { case 0: { pid_t pid = data.readInt32(); int num = data.readInt32(); num = num + 1000; reply->writeInt32(num); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } };
Android.mk 文件:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= AddService.cpp #LOCAL_C_INCLUDES:= $(JNI_H_INCLUDE) LOCAL_SHARED_LIBRARIES:= libutils LOCAL_MODULE:= libAddService LOCAL_PRELINK_MODULE:= false
include $(BUILD_SHARED_LIBRARY)
Step-2 :以 C++ 撰写一个可独立执行的 addserver.cpp 程序,它的用途是:诞生一个 AddService 类别之对象,然后将该对象参考存入 Binder Driver 里。其内容为:
addserver.cpp 文件:
#include <sys/types.h> #include <unistd.h> #include <grp.h> #include <utils/IPCThreadState.h> #include <utils/ProcessState.h> #include <utils/IServiceManager.h> #include <utils/Log.h> #include <private/android_filesystem_config.h> #include "../libaddservice/AddService.h" using namespace android; int main(int argc, char** argv) { sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); LOGI("ServiceManager: %p", sm.get()); AddService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }
Android.mk 文件:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= addserver.cpp LOCAL_SHARED_LIBRARIES:= libutils libAddService LOCAL_MODULE:= addservice include $(BUILD_EXECUTABLE)
Step-3 :编译上述两个文件分别产出了 libAdd.so 类别库和 addserver 可执行程序。接着将 libAdd.so 拷贝到 Android 仿真器的 /system/lib/ 里;也把 addserver 拷贝到 /system/bin/ 里。
Step-4 :执行 addserver 。其中的指令: AddServer::instantiate() 就执行到 AddServer 类别的 instantiate() 函数,其内容为:
int AddService::instantiate() { LOGE("AddService instantiate"); int r = defaultServiceManager()->addService( String16("guilh.add"), new AddService()); LOGE("AddService r = %d/n", r); return r; }
其先执行到 new AddServer() ,就诞生一个 AddServer 类别之对象;
接着,呼叫 defaultServiceManager() 函数取得 SM 的 IServiceManager 接口;
再呼叫 IServiceManager::addServer() 将该对象参考存入 Binder Driver 里。
Step-5 :这样就成功地将 AddService 服务加入到 Binder Driver 里了。现在就可以写个 Add 类来使用 AddService 核心服务了。以 C++ 撰写 Add 类别,其完整程序代码为:
Add.h 文件:
#ifndef ANDROID _ADD_H #define ANDROID _ADD_H namespace android { class Add { public: int setN(int n); private: static const void getAddService(); }; }; //namespace #endif // ANDROID _ADD_H
Add.cpp 文件:
#include <utils/IServiceManager.h> #include <utils/IPCThreadState.h> #include "Add.h" namespace android { sp<IBinder> binder; int Add::setN(int n){ getAddService(); Parcel data, reply; data.writeInt32(getpid()); data.writeInt32(n); LOGE("BpAddService::create remote()->transact()/n"); binder->transact(0, data, &reply); int i = reply.readInt32(); return i; } const void Add::getAddService(){ sp<IServiceManager> sm = defaultServiceManager(); binder = sm->getService(String16("guilh.add")); LOGE("Add::getAddService %p/n",sm.get()); if (binder == 0) { LOGW("AddService not published, waiting..."); return; } } };
Android.mk 文件:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:=Add.cpp LOCAL_SHARED_LIBRARIES := libutils libAddService LOCAL_MODULE := libAdd LOCAL_PRELINK_MODULE:= false include $(BUILD_SHARED_LIBRARY)
Step-6 :下面写个 JNI Native 类别来使用 Add 类别之对象。透过 JNI Native 函数,就可以与 Java 层的 Service 服务衔接起来。
首选使用 javah 命令生成相应头文件。
com_hello_Service_MySer.h 文件:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_hello_Service_MySer */ #ifndef _Included_com_hello_Service_MySer #define _Included_com_hello_Service_MySer #ifdef __cplusplus extern "C" { #endif /* * Class: com_hello_Service_MySer * Method: intFromJNI * Signature: ()I */ JNIEXPORT jint JNICALL Java_com_hello_Service_MySer_intFromJNI (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif 然后实现相应函数。 com_hello_Service_MySer.cpp 文件: #include <jni.h> #include <JNIHelp.h> #include "../libadd/Add.h" #include "com_hello_Service_MySer.h" JNIEXPORT jint JNICALL Java_com_hello_Service_MySer_intFromJNI(JNIEnv * env, jobject thiz) { android::Add myadd; int r = myadd.setN(5); return r; }
Android.mk 文件:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:=com_hello_Service_MySer.cpp LOCAL_C_INCLUDES:= $(JNI_H_INCLUDE) LOCAL_SHARED_LIBRARIES := libutils libAdd LOCAL_MODULE := libJniAdd LOCAL_PRELINK_MODULE:= false include $(BUILD_SHARED_LIBRARY)
所有相关文件组织:
a@ubuntu:~/work/android/source_android/development/my_module$ tree service
service
|-- addserver
| |-- Android.mk
| `-- addserver.cpp
|-- jni
| |-- Android.mk
| |-- com_hello_Service_MySer.cpp
| `-- com_hello_Service_MySer.h
|-- libadd
| |-- Add.cpp
| |-- Add.h
| `-- Android.mk
`-- libaddservice
|-- AddService.cpp
|-- AddService.h
`-- Android.mk
4 directories, 11 files
在 Eclipse 中创建一个工程使用以上的 Add 类,即可使用我们的 AddService 了。
MySer.java 文件:
package com.hello.Service; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class MySer extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); int i = intFromJNI(); TextView tv = new TextView(this); tv.setText( String.valueOf(i) ); setContentView(tv); } public native int intFromJNI(); static { System.loadLibrary("JniAdd"); } }
五、Service 编译问题
Android 所用的 Toolchain (即交叉编译工具链)可从下面的网址下载:
http://android.kernel.org/pub/android-toolchain-20081019.tar.bz2 。如果下载了完整的 Android 项目的源代码,则可以在“<your_android>/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin ”目录下找到交叉编译工具,比如 Android 所用的 arm-eabi-gcc-4.2.1 。我们可以直接使用源码包来进行编译。
Android 并没有采用 glibc 作为 C 库,而是采用了 Google 自己开发的 Bionic Libc ,它的官方 Toolchain 也是基于Bionic Libc 而并非 glibc 的。这使得使用或移植其他 Toolchain 来用于 Android 要比较麻烦:在 Google 公布用于Android 的官方 Toolchain 之前,多数的 Android 爱好者使用的 Toolchain 是在http://www.codesourcery.com/gnu_toolchains/arm/download.html 下载的一个通用的 Toolchain ,它用来编译和移植Android 的 Linux 内核是可行的,因为内核并不需要 C 库,但是开发 Android 的应用程序时,直接采用或者移植其他的Toolchain 都比较麻烦,其他 Toolchain 编译的应用程序只能采用静态编译的方式才能运行于 Android 模拟器中,这显然是实际开发中所不能接受的方式。目前尚没有看到说明成功移植其他交叉编译器来编译 Android 应用程序的资料。
与 glibc 相比, Bionic Libc 有如下一些特点:
l 采用 BSD License ,而不是 glibc 的 GPL License ;
l 大小只有大约 200k ,比 glibc 差不多小一半,且比 glibc 更快;
l 实现了一个更小、更快的 pthread ;
l 提供了一些 Android 所需要的重要函数,如” getprop ” , “ LOGI ”等;
l 不完全支持 POSIX 标准,比如 C++ exceptions , wide chars 等;
l 不提供 libthread_db 和 libm 的实现
另外, Android 中所用的其他一些二进制工具也比较特殊:
加载动态库时使用的是 /system/bin/linker 而不是常用的 /lib/ld.so;
prelink 工具不是常用的 prelink 而是 apriori ,其源代码位于“ <your_android>/build/tools/apriori ”
strip 工具也没有采用常用的 strip ,而是“ <your_android>/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin ”目录下的arm-eabi-strip ,而是位于 <your_android>/out/host/linux-x86/bin/ 的 soslim 工具。
下面就具体说一下如何编译我们刚才创建的 Service 程序。
1. 在 $(YOUR_ANDROID)/development 目录下创建 my_module 目录,然后将我们的 server 文件夹拷贝到此目录下,其中$(YOUR_ANDROID) 指 Android 源代码所在的目录。
# mkdir $(YOUR_ANDROID)/development/ my_module
2. Android.mk 这是 Android Makefile 的标准命名,不要更改。 Android.mk 文件的格式和内容可以参考其他已有的Android.mk 文件的写法,针对 Add 程序的 Android.mk 文件内容如下:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:=Add.cpp LOCAL_SHARED_LIBRARIES := libutils libAddService LOCAL_MODULE := libAdd LOCAL_PRELINK_MODULE:= false include $(BUILD_SHARED_LIBRARY)
注意上面 LOCAL_SRC_FILES 用来指定源文件;, LOCAL_MODULE 指定要编译的模块的名字,下一步骤编译时就要用到; include $(BUILD_SHARED_LIBRARY) 表示要编译成动态库,如果想编译成一个可执行文件则可用BUILD_EXECUTABLE ,这些可以在 $(YOUR_ANDROID)/build/core/config.mk 查到。
3. 回到 Android 源代码顶层目录进行编译:
# cd $(YOUR_ANDROID) && make libAdd
注意 make libAdd 中的目标名 libAdd 就是上面 Android.mk 文件中由 LOCAL_MODULE 指定的模块名。
4 .编译后的可执行文件存放在通过” adb push ”将它传送到模拟器上,再通过” adb shell ”登录到模拟器终端,就可以执行了。
六、出现问题及及解决办法:
( 1 )提示缺 bison ,安装 bison : sudo apt-get install bison
( 2 )出现 frameworks/policies/base/PolicyConfig.mk:22: *** No module defined for the given PRODUCT_POLICY (android.policy_phone). Stop. 错误。
解决办法:
在 build/tools/findleaves.sh 中的第 89 行,
这一句 find "${@:0:$nargs}" $findargs -type f -name "$filename" -print |
改为 find "${@:1:$nargs-1}" $findargs -type f -name "$filename" -print |
转载:http://blog.chinaunix.net/u/22630/article_105768.html
发表评论
-
JAVA代码混淆
2016-05-05 18:24 1466JAVA代码混淆 <!--[if !supportL ... -
android 监听状态栏被下拉
2015-12-25 17:23 3499Activity的onWindowFocusChange()方 ... -
android使用mount挂载/system/app为读写权限,删除或替换系统应用
2015-11-27 14:13 4041注意:以下代码中#开头的则为需要执行的shell命令,其他的 ... -
Ubuntu 14.04 文件服务器--samba的安装和配置
2015-11-10 10:49 645jingyan.baidu.com/album/00a07f ... -
intellij 打开工程在每个java文件上 有个红色的无效符
2015-07-24 13:52 1776说明该类不是可编译文件。在project Structure中 ... -
logcat命令详解
2015-07-22 16:34 996Android日志系统提供了记录和查看系统调试信息的功能。日 ... -
gradle打包遇到的错误汇总
2015-07-21 11:32 0错误1:A problem occurred ... -
Android读写XML(下)——创建XML文档
2015-04-29 11:02 624在前面的2篇文章Android读写XML(上)—— pack ... -
Android读写XML(中)——SAX
2015-04-29 10:54 628在Android读写XML(上) ... -
Android读写XML(下)——创建XML文档
2015-04-29 10:52 710在前面的2篇文章Android读写XML(上)—— pack ... -
android:configChanges locale 改语言后,该配置不起作用的原因
2015-03-23 14:38 2546@Override public void on ... -
android.app.Fragment$InstantiationException 解决办法
2015-03-23 13:46 1425android.app.Fragment$Instantia ... -
linux 查看内存
2015-02-10 13:08 7551、free监控内存使用情况 #free 2、watc ... -
android fastboot 刷机 指令
2015-01-19 18:31 1539原生bootloader:bootloader-gro ... -
[Android实例] android中进行https连接的方式的详解 (转发)
2015-01-09 15:50 701x 如果不需要验证服务器端证书, ... -
编译android源码apk是否生成odex方法
2014-10-20 17:19 1658其实Android系统默认的配置是,如果没有指定DISABL ... -
关于android源码中的APP编译时引用隐藏的API出现的问题
2014-10-20 15:36 860今天在编译android源码中的计算器APP时发现,竟然无法 ... -
Android系统进程Zygote启动过程的源代码分析
2014-09-17 10:09 518在Android系统中, ... -
Handler和HandlerThread
2014-09-16 16:58 7011.什么是Handler? SDK中关于Handler的说 ... -
怎样识别三洋18650锂电池电芯
2014-09-01 09:52 1132浏览:20384 | 更新:2011-03 ...
相关推荐
本教程将详细介绍如何使用Android Service来实现文件下载,并在前台显示进度,同时通过通知栏同步更新下载进度。 首先,我们需要创建一个服务类(Service)来处理下载任务。在Android Studio中,可以通过右键点击...
"Android Service实现断点下载"是一个实用的功能,允许用户在任意时间点暂停下载任务,并在稍后继续从停止的地方开始,无需重新下载已完成的部分。这种功能极大地提升了用户体验,尤其是在处理大文件或者网络不稳定...
在Android应用开发中,Service是一种在后台运行的组件,它不具有用户界面,但可以执行长时间的任务或与其他组件进行通信。在某些情况下,我们可能需要一个Service去执行一些任务,并在任务完成后更新UI。这时,我们...
本篇文章将详细介绍Android Service的实现过程。 首先,创建一个Service需要继承自`android.app.Service`类,并重写其关键方法。这些方法包括: 1. `onCreate()`:Service的生命周期开始时调用,用于初始化服务。...
"Android之实现app更新,实现service下载.zip"这个压缩包文件显然包含了关于如何在Android系统中实现后台服务(Service)进行App更新的技术资料。让我们深入探讨这个主题。 首先,Android App更新通常有两种方式:...
"Android Service Demo"是一个示例项目,它展示了如何在Android应用中使用Service,尤其是结合AIDL(Android Interface Definition Language)来实现进程间通信(IPC,Inter-Process Communication)。 首先,我们...
综上所述,"android service下载资源,同时解压资源"这一功能实现涉及到了Android Service、异步下载、BroadcastReceiver、ZIP文件解压等多个技术点,这些知识点在实际的Android应用开发中都非常常见且重要。...
在Android平台上,录音功能是通过Android SDK提供的MediaRecorder类实现的。Service是Android四大组件之一,用于在后台长时间运行任务,不受用户界面交互的影响。在这个"android 录音机 service 例子"中,我们将深入...
以上就是利用Service实现通话录音的基本流程和关键知识点。在实际开发中,可能还需要根据不同的设备和系统版本进行适配。务必注意处理各种异常情况,以提供稳定可靠的录音体验。通过不断学习和实践,你将能够熟练...
8. **调试与优化**:在开发过程中,使用Android Studio的Logcat工具进行日志输出,可以帮助调试Service的生命周期和功能。同时,要注意优化Service的资源使用,避免影响用户的设备性能和电池寿命。 综上所述,QT ...
本文将详细解析Android下载实现的过程,并基于提供的"DRM"这一标签,探讨可能涉及的数字版权管理(Digital Rights Management)技术。 首先,让我们来看看Android下载的基本流程: 1. **创建DownloadManager**: ...
### Android Service 学习(下): 进程间通信与 AIDL 在深入探讨 Android Service 的高级用法时,我们不可避免地会接触到进程间通信(IPC)这一关键概念。由于 Android 应用程序通常在各自独立的进程中运行,因此它们...
Service的源码分析还可以深入到AIDL(Android Interface Definition Language)层面,它是实现跨进程通信的重要工具。当Service需要在不同进程中运行或者被远程组件调用时,AIDL就显得尤为重要。通过AIDL定义的接口...
本案例“android音乐播放器service学习案例”着重讲解如何利用Service来实现一个音乐播放器,使音乐能够在后台持续播放。 首先,我们需要了解Android Service的基础知识。Service分为两种类型:标准服务...
在Android应用开发中,Service是实现后台运行任务的关键组件,它可以独立于用户界面持续执行操作。本主题将深入探讨如何使用Service以及BroadcastReceiver来实现特定的功能:当Service检测到某个函数的状态变化时,...
AIDL(Android Interface Definition Language)是Android系统提供的一种接口定义语言,用于在不同进程间进行通信,特别是当服务(Service)需要与客户端(如Activity)跨进程交互时。AIDL帮助开发者定义接口,使得...
通过本帖,我们可以了解到如何使用 Android 的 Service 和 Activity 实现基于串口蓝牙模块的双向通信。这种通信方式可以用来控制家电、智能小车等设备。 首先,作者提到使用手机控制家电的想法,并且介绍了使用蓝牙...
在描述中提到的“坑”可能指的是在通信过程中遇到的问题,例如Service生命周期管理不当导致内存泄漏,或者Activity和Service之间的同步问题。开发者需要确保在Activity销毁时正确解除与Service的连接,防止Service被...
在Android平台上实现UPnP技术,可以让移动设备与其他支持UPnP的设备,如智能电视、打印机、路由器等进行无缝交互,实现媒体共享、远程控制等功能。这份"Android高级应用源码-UPnP Android代码实现"的压缩包,很显然...
在Android应用开发中,`Service` 是一个非常重要的组件,用于执行长时间运行的操作,比如后台音乐播放、文件下载等。本篇文章将详细讲解如何利用`Service` 实现带有进度条的文件下载功能。 首先,我们需要创建一个`...