Android制作service以及sdk并打包成jar包
项目中需要把连接服务器的部分做成一个service并生成一个jar模块。其他产品就可通过这个包来快速的开发连接服务器的应用软件。做成一个service的优点是:
1. 在后台运行,可以一直保持与服务器的连接
2. 服务可以只对外提供接口,具体功能在服务内部实现
3. 增加项目代码的耦合性
当然你不想拿着一个service的源代码分享给别人。你需要把这个服务打包成一个jar包。并且打包的时候可以选择代码混淆,加强代码的易破解性。
我打包这样一个服务也不是突发奇想。是在使用佳博打印机开发项目的时候,使用了人家的连接sdk有的感触。我们开发的时候只需把jar库导入到项的libs文件夹。然后就可以通过sdk接口文档描述的函数来初始化打印服务并使用打印功能。
那么接下来就说一下怎样开发服务并且打包成一个jar文件并对外提供接口。即完成一个sdk的制作。
这里先说一下打包主要是在打包方面费了很多时间。首先我们知道eclipse可以很方便的打包为jar。但是由于使用了一段时间Android studio 所以就想在Android studio 导出jar包。我也是第一次这样做。遇到了好大的阻力,Android studio那一大堆文件夹真要把人给逼疯了。
本来看着一篇文章对Android studio 生成jar做了验证。文章地址为:
http://blog.csdn.net/ta893115871/article/details/46955791
但是在实际操作中,新建了一个存放service的module(文章里提到的生成库的叫法)作为主工程的子项目,但是这样的话主项目无法调用这个module里面的服务。让测试很沮丧。
文章图片
虽然不能测试,但是好歹生成一个jar包,里面也包含了我需要打包的文件,但是呢,关键是但是,给附加了其它的文件是个什么意思。哎算了吧。上面截图中左下角的是使用jd-gui(java decompiler)查看jar包内容的截图。右面为生成的jar文件,背景为工程。
Android studio有自己的好处,但是在自己制作sdk的时候还是使用eclipse吧。当然把Android service代码和调用代码放在一个工程下在Android studio是可以正常使用的,下面打开几个我使用的第三方sdk的jar包看看:
文章图片
文章图片
这是微信的语音识别sdk的jar包的内容
文章图片
这是我用eclipse生产的jar的内容,因此我觉得腾讯是用的eclipse打包的jar文件
Eclipse 打包jar的方式参照文章:http://blog.csdn.net/wantianpei/article/details/7638483
Eclipse打包jar的时候可以选择哪些文件打包到jar里.
制作所用的工具以及方式已经说明白了,下面接着介绍关于service的详细开发。
我们一般开发一个sdk当然是定义远程的service,也就是通过bingservice启动的方式来启动的服务。
同时,应用和服务通信的方式有Messenger和aidl,具体区别看别人的文章吧。
我们这里是开发一个sdk,因此选择了使用aidl,当然如果你的sdk并不包含任何服务,就没有这回事儿了。
现在以一个例子描述创建一个服务并调用的过程。例子的功能是设置一个数字的值到服务里,然后在从服务里读出来。主界面用于放置了两个按键用于触发以上两个动作,调用的结果在logcat里显示。
使用eclipse作为工具:
首先创建一个工程,,然后在项目src下面创建一个包,用于放置服务的代码以及一个包用于放置aidl文件。包内依次放置了服务类和aidl文件。创建完之后,内容如下。
文章图片
其中CloudServiceInterface.aidl文件内容如下:
packagecom.rayleigh.aidl;
interfaceCloudServiceInterface {
void setInfo(intperson);
intgetInfo();
}
CloudService.java文件文件内容如下:
packagecom.rayleigh.cloud;
importcom.rayleigh.aidl.CloudServiceInterface;
import android.app.Service;
importandroid.content.Intent;
importandroid.os.IBinder;
importandroid.util.Log;
publicclass CloudService extends Service {
private int testdata = https://www.it610.com/article/0;
public CloudService() {
}
private static final StringTAG="Test";
@Override
public void onCreate()
{
Log.i(TAG, "ServiceonCreate--->");
//TODO:register broadcast
TODO: 2016/12/18or start do something
super.onCreate();
}
@Override
public int onStartCommand(Intent intent,int flags, int startId) {
// return super.onStartCommand(intent,flags, startId);
return START_STICKY;
}
@Override
public void onDestroy()
{
Log.i(TAG, "ServiceonDestroy--->");
//TODO: unregister broadcast
super.onDestroy();
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "Serviceonunbind--->");
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
Log.i(TAG, "Serviceonrebond--->");
super.onRebind(intent);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communicationchannel to the service.
// throw new UnsupportedOperationException("Notyet implemented");
return mBinder;
}
private final CloudServiceInterface.StubmBinder = new CloudServiceInterface.Stub() {
@Override
public void setInfo(int person){
testdata = https://www.it610.com/article/person;
}
@Override
public int getInfo(){
return testdata;
}
};
}
然后点击project->clean,来编译项目。就会在gen目录里生成了CloudServiceInterface.aidl所用对应的CloudServiceInterface.java。如下:
文章图片
然后在AndroidMannifest.xml里面添加服务声明:
android:process=":remote"
>
然后在MainActivity.java里面定义服务对象:
CloudServiceInterfacemService;
private ServiceConnectionserviceConnection =new ServiceConnection() {
@Override
publicvoid onServiceConnected(ComponentName componentName,IBinder iBinder) {
Log.e("on","on service connected");
mService = CloudServiceInterface.Stub.asInterface(iBinder);
}
@Override
publicvoid onServiceDisconnected(ComponentName componentName) {
Log.e("on","on service disconnected");
mService = null;
}
};
【Android制作service以及sdk并打包成jar包】
然后调用bindService函数启用服务。我定义成函数如下:
private void connectionToService() {
Intent intent=newIntent(MainActivity.this,CloudService.class);
this.getApplicationContext().bindService(intent,serviceConnection,Context.BIND_AUTO_CREATE);
}
在onCreate里面调用此函数。
最后onCreate里面的内容如下:
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startBtn = (Button)findViewById(R.id.StartBtn);
stopBtn = (Button) findViewById(R.id.StopBtn);
startBtn.setOnClickListener(listener);
stopBtn.setOnClickListener(listener);
connectionToService();
}
其中按键点击响应函数如下:
private View.OnClickListener listener =newView.OnClickListener()
{
@Override
public void onClick(Viewv)
{
switch (v.getId())
{
case R.id.StartBtn:
if (mService != null){
try {
mService.setInfo(3);
Log.e("mainactivity","setvalue success");
} catch (Exceptione){
}
} else {
Log.e("mainactivity","mServiceis null");
}
break;
case R.id.StopBtn:
if (mService != null){
try {
int a= mService.getInfo();
Log.e("mainactivity","getvalue is :"+ a);
} catch (Exceptione) {
}
} else {
Log.e("mainactivity","mServiceis null");
}
break;
default:
break;
}
}
};
分别点击两个按键来,设置数字到服务里,和从服务里获取数据
这个例子很简单,看代码就可以了
源码下载连接
然后导出jar包:
包的内容有:CloudService.java,CloudServiceInterface.aidl
步骤为File->Export,然后选择java。JAR file,选择Next
选择我的内容为:
文章图片
填写的保持jar的路径
文章图片
文章图片
然后finish就生成了自己的jar包,
用jd-gui查看jar包内容如下:
文章图片
为了测试这个包好不好用,你可以在新建一个工程,导入这个包,然后,在新建的项目下面建立com.rayleigh.aidl包,并在里面手动建立CloudServiceInterface.aidl文件。并在里面放置内容如下:
packagecom.rayleigh.aidl;
interfaceCloudServiceInterface {
void setInfo(intperson);
intgetInfo();
}
然后clean一下。生成对应的java文件。
然后在Androidmannifest.xml文件里加入service生命,就和上面测试的时候一样的内容。然后在新建立的项目的mainacivity.java加入和测试是一样功能的代码。也就是说新的测试工程和之前建立jar包的项目唯一的区别是少了服务实现文件即,“CloudService.java”
至此,如果你这个jar包给用户使用,你就可以把你aidl里面函数功能说用写到一个介绍文档里面,并且加入建立aidl文件的说明。就可以作为开发文档。
本文所编写的代码可以在以下地址找到:
http://download.csdn.net/detail/robert_cysy/9717990
推荐阅读
- android第三方框架(五)ButterKnife
- Android中的AES加密-下
- 带有Hilt的Android上的依赖注入
- android|android studio中ndk的使用
- Android事件传递源码分析
- RxJava|RxJava 在Android项目中的使用(一)
- Android7.0|Android7.0 第三方应用无法访问私有库
- 深入理解|深入理解 Android 9.0 Crash 机制(二)
- android防止连续点击的简单实现(kotlin)
- Android|Android install 多个设备时指定设备