远程Service及Sqlite示例
- 先创建RemoteServiceServer 远程Service服务端
- 新建一个aidl,并命名为IMyAidlInterface.aidl,文件里的代码如下:
// IMyAidlInterface.aidl
// 在新建的IMyAidlInterface.aidl里声明需要与Activity进行通信的方法
package com.dlrj.remoteserviceserver;
import com.dlrj.remoteserviceserver.StudentInfo;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
void AIDL_Service();
void setStudentInfos(in List
void addStudentInfo(in StudentInfo studentInfo);
List
StudentInfo getStudentInfo(int id);
int getStudentId(String studentName);
int delete(int id, String name, String gender, int grade, int class_);
List
}
//AIDL中支持以下的数据类型
//1. 基本数据类型
//2. String 和CharSequence
//3. List 和 Map ,List和Map 对象的元素必须是AIDL支持的数据类型;
//4. AIDL自动生成的接口(需要导入-import)
//5. 实现android.os.Parcelable 接口的类(需要导入-import)
由于我们示例中传输的数据对象继承Parcelable,所以需要另外新建一个aidl,命名为StudentInfo.aidl,并且需要定义StudentInfo为parcelable类型,注意parcelable在aidl中必须小写
// StudentInfo.aidl
package com.dlrj.remoteserviceserver;
// Declare any non-default types here with import statements
parcelable StudentInfo;
StudentInfo代码实现如下:
package com.dlrj.remoteserviceserver;
import android.os.Parcel;
import android.os.Parcelable;
public class StudentInfo implements Parcelable {
private String name; //姓名
private int id; //学号
private String gender; //性别
private int grade; //年级
private int class_; //班级
public StudentInfo() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public int getClass_() {
return class_;
}
public void setClass_(int class_) {
this.class_ = class_;
}
// @Override
// public String toString() {
// return "book name:" + name;
// }
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
dest.writeInt(id);
dest.writeString(gender);
dest.writeInt(grade);
dest.writeInt(class_);
}
public void readFromParcel(Parcel dest) {
name = dest.readString();
id = dest.readInt();
gender = dest.readString();
grade = dest.readInt();
class_ = dest.readInt();
}
protected StudentInfo(Parcel in) {
// this.name = in.readString();
// this.id = in.readInt();
// this.gender = in.readString();
// this.grade = in.readInt();
// this.class_ = in.readInt();
this.readFromParcel(in);
}
public static final Creator
@Override
public StudentInfo createFromParcel(Parcel source) {
return new StudentInfo(source);
}
@Override
public StudentInfo[] newArray(int size) {
return new StudentInfo[size];
}
};
}
- 新建一个Service,并命名为MyService,并在Service里面实现对sqlite数据库的操作,代码实现如下
package com.dlrj.remoteserviceserver;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class MyService extends Service {
private static final String LOG_PRINT_TAG = "MyService";
// private List
private DBHelper dbHelper = null;
IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {
@Override
public void AIDL_Service() throws RemoteException {
Log.e(LOG_PRINT_TAG, "客户端调用了IMyAidlInterface.Stub的AIDL_Service方法");
if (dbHelper == null) {
dbHelper = new DBHelper(getApplicationContext());
}
}
@Override
public void setStudentInfos(@NonNull List
// studentNames = studendNames_;
}
@Override
public void addStudentInfo(@NonNull StudentInfo studentInfo) throws RemoteException {
dbHelper.update(studentInfo);
}
@Override
public List
return dbHelper.getStudentInfoList();
}
@Override
public StudentInfo getStudentInfo(int id) {
ArrayList
if (studentInfoList.isEmpty()) {
return null;
}
if (id < 0 || id >= studentInfoList.size()) {
return null;
}
return studentInfoList.get(id);
}
@Override
public int getStudentId(String studentName) {
ArrayList
if (studentInfoList.isEmpty()) {
return -1;
}
if (studentName == null || studentName.trim().length() < 1) {
return -1;
}
for (int i = 0; i < studentInfoList.size(); i++) {
StudentInfo studentInfo = studentInfoList.get(i);
if (studentInfo != null && studentInfo.getName() == studentName) {
return i;
}
}
return -1;
}
@Override
public int delete(int id, String name, String gender, int grade, int class_) throws RemoteException {
return dbHelper.delete(id, name, gender, grade, class_);
}
@Override
public List
return dbHelper.queryByCondition(id, name, gender, grade, class_);
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e(LOG_PRINT_TAG, "执行了onBind()");
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.e(LOG_PRINT_TAG, "执行了onUnbind()");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
super.onCreate();
Log.e(LOG_PRINT_TAG, "执行了onCreate()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(LOG_PRINT_TAG, "执行了onStartCommand()" + flags + " " + startId);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
if (dbHelper != null) {
dbHelper.close();
}
Log.e(LOG_PRINT_TAG, "执行了onDestroy()");
}
}
在AndroidManifest.xml里添加下面代码
android:exported="true">
android:process=":remote" 一定要设置为remote 远程Service 其他应用也能通过名字,启动并绑定我们的远程服务
- 新建一个数据库管理类DBHelper,代码如下
package com.dlrj.remoteserviceserver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.Vector;
public class DBHelper extends SQLiteOpenHelper {
private static final String LOG_PRINT_TAG = "MyService";
private static final String TABLE_NAME = "Student";
//T_R table_row
public static final String T_R_NAME = "name";
public static final String T_R_ID = "id";
public static final String T_R_GENDER = "gender";
public static final String T_R_GRADE = "grade";
public static final String T_R_CLASS = "class_";
public static final String CREATE_BOOK = "create table " + TABLE_NAME + " ( "
+ T_R_ID + " integer primary key autoincrement,"
+ T_R_GENDER + " text,"
+ T_R_GRADE + " integer,"
+ T_R_CLASS + " integer,"
+ T_R_CLASS + " text)";
private static final int VERSION = 1;
private ArrayList
private int lastMissId = 0; //上一个缺失的学号
public DBHelper(@Nullable Context context) {
super(context, TABLE_NAME, null, VERSION);
studentInfoList = new ArrayList
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + TABLE_NAME); //删除表
onCreate(db); //重新创建表
}
private long insert(StudentInfo studentInfo, SQLiteDatabase db, int id) {
Log.e(LOG_PRINT_TAG, "insert");
boolean isGet = false;
if (db == null) {
db = this.getWritableDatabase();
isGet = true;
}
ContentValues values = new ContentValues();
if (id > 0) {
values.put(T_R_ID, id);
}
values.put(T_R_NAME,studentInfo.getName());
values.put(T_R_GENDER,studentInfo.getGender());
values.put(T_R_GRADE,studentInfo.getGrade());
values.put(T_R_CLASS,studentInfo.getClass_());
long insertnum = 0;
if (id > 0) {
insertnum = db.insert(TABLE_NAME,T_R_ID,values);
} else {
insertnum = db.insert(TABLE_NAME,null,values);
}
Log.e(LOG_PRINT_TAG, "insert insertnum = " + insertnum);
if (insertnum > 0) {
this.queryAll();
}
return insertnum;
}
public int update(StudentInfo studentInfo) {
Log.e(LOG_PRINT_TAG, "update " + studentInfo.toString());
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(T_R_NAME,studentInfo.getName());
values.put(T_R_GENDER,studentInfo.getGender());
values.put(T_R_GRADE,studentInfo.getGrade());
values.put(T_R_CLASS,studentInfo.getClass_());
int effectRowNum = db.update(TABLE_NAME, values, T_R_NAME + "=?", new String[]{ studentInfo.getName()});
Log.e(LOG_PRINT_TAG, "update effectRowNum = " + effectRowNum);
if (effectRowNum > 0) { //如果更新表失败
this.queryAll();
} else { //则进行插入表操作
findIdInfos(); //查找缺失的id信息
effectRowNum = (int) this.insert(studentInfo, db, lastMissId); //插入的位置,如果为0是,是往上一条后面插入数据 返回影响的行数 行数大于0,插入表成功
}
return effectRowNum;
}
private void findIdInfos() {
Log.e(LOG_PRINT_TAG, "findIdInfos");
ArrayList
lastMissId = 0;
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
StudentInfo studentInfo = list.get(i);
if ((i + 1) != studentInfo.getId()) {
lastMissId = i + 1;
Log.e(LOG_PRINT_TAG, "findIdInfos lastMissId = " + lastMissId);
break;
}
}
}
}
public int delete(int id, String name, String gender, int grade, int class_) {
SQLiteDatabase db = this.getWritableDatabase();
StringBuilder conditions = new StringBuilder();
Vector
if (id > 0) {
conditions.append(T_R_ID + "=?");
vecConditionDatas.add("" + id);
}
if (name != null && name.length() > 0) {
if (conditions.length() > 0) {
conditions.append("," + T_R_NAME + "=?");
} else {
conditions.append(T_R_NAME + "=?");
}
vecConditionDatas.add(name);
}
if (gender != null && gender.length() > 0) {
if (conditions.length() > 0) {
conditions.append("," + T_R_GENDER + "=?");
} else {
conditions.append(T_R_GENDER + "=?");
}
vecConditionDatas.add(gender);
}
if (grade > 0) {
if (conditions.length() > 0) {
conditions.append("," + T_R_GRADE + "=?");
} else {
conditions.append(T_R_GRADE + "=?");
}
vecConditionDatas.add("" + grade);
}
if (class_ > 0) {
if (conditions.length() > 0) {
conditions.append("," + T_R_CLASS + "=?");
} else {
conditions.append(T_R_CLASS + "=?");
}
vecConditionDatas.add("" + class_);
}
Log.e(LOG_PRINT_TAG, "queryByCondition conditions = " + conditions);
String[] conditionDatas = new String[vecConditionDatas.size()];
for (int i = 0; i < vecConditionDatas.size(); i++) {
conditionDatas[i] = vecConditionDatas.get(i);
}
int effectRowNum = db.delete(TABLE_NAME, conditions.toString(), conditionDatas);
if (effectRowNum > 0) {
this.queryAll();
}
return effectRowNum;
}
public ArrayList
SQLiteDatabase db = this.getReadableDatabase();
StringBuilder conditions = new StringBuilder(); //精确查找条件
StringBuilder conditions2 = new StringBuilder(); //模糊查找条件
Vector
if (id > 0) {
conditions.append(T_R_ID + "=?");
conditions2.append(T_R_ID + " LIKE ?");
vecConditionDatas.add("" + id);
}
if (name != null && name.length() > 0) {
if (conditions.length() > 0) {
conditions.append("," + T_R_NAME + "=?");
conditions2.append("," + T_R_NAME + " LIKE ?");
} else {
conditions.append(T_R_NAME + "=?");
conditions2.append(T_R_NAME + " LIKE ?");
}
vecConditionDatas.add(name);
}
if (gender != null && gender.length() > 0) {
if (conditions.length() > 0) {
conditions.append("," + T_R_GENDER + "=?");
conditions2.append("," + T_R_GENDER + " LIKE ?");
} else {
conditions.append(T_R_GENDER + "=?");
conditions2.append(T_R_GENDER + " LIKE ?");
}
vecConditionDatas.add(gender);
}
if (grade > 0) {
if (conditions.length() > 0) {
conditions.append("," + T_R_GRADE + "=?");
conditions2.append("," + T_R_GRADE + " LIKE ?");
} else {
conditions.append(T_R_GRADE + "=?");
conditions2.append(T_R_GRADE + " LIKE ?");
}
vecConditionDatas.add("" + grade);
}
if (class_ > 0) {
if (conditions.length() > 0) {
conditions.append("," + T_R_CLASS + "=?");
conditions2.append("," + T_R_CLASS + " LIKE ?");
} else {
conditions.append(T_R_CLASS + "=?");
conditions2.append(T_R_CLASS + " LIKE ?");
}
vecConditionDatas.add("" + class_);
}
Log.e(LOG_PRINT_TAG, "queryByCondition conditions = " + conditions);
String[] conditionDatas = new String[vecConditionDatas.size()];
String[] conditionDatas2 = new String[vecConditionDatas.size()];
for (int i = 0; i < vecConditionDatas.size(); i++) {
conditionDatas[i] = vecConditionDatas.get(i);
conditionDatas2[i] = "%" + vecConditionDatas.get(i) + "%";
}
ArrayList
Cursor cursor = null;
cursor = db.query(TABLE_NAME, new String[]{T_R_ID,T_R_NAME,T_R_GENDER, T_R_GRADE, T_R_CLASS},
conditions.toString(), conditionDatas, null, null, null); //精确查找
if (cursor.getCount() < 1) {
cursor = db.query(TABLE_NAME, new String[]{T_R_ID,T_R_NAME,T_R_GENDER, T_R_GRADE, T_R_CLASS}, conditions2.toString(),
conditionDatas2, null, null, null); //模糊查找
}
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
int id_=cursor.getInt(0);
String name_=cursor.getString(1);
String gender_ =cursor.getString(2);
int grade_ = cursor.getInt(3);
int class__ = cursor.getInt(4);
StudentInfo studentInfo = new StudentInfo();
studentInfo.setId(id_);
studentInfo.setName(name_);
studentInfo.setGender(gender_);
studentInfo.setGrade(grade_);
studentInfo.setClass_(class__);
studentInfos.add(studentInfo);
// do something useful with these
cursor.moveTonext();
}
cursor.close();
return studentInfos;
}
public void queryAll() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, new String[]{T_R_ID,T_R_NAME,T_R_GENDER, T_R_GRADE, T_R_CLASS},
null, null, null, null, null);
cursor.moveToFirst();
studentInfoList.clear();
while (!cursor.isAfterLast()) {
int id=cursor.getInt(0);
String name=cursor.getString(1);
String gender =cursor.getString(2);
int grade = cursor.getInt(3);
int class_ = cursor.getInt(4);
StudentInfo studentInfo = new StudentInfo();
studentInfo.setId(id);
studentInfo.setName(name);
studentInfo.setGender(gender);
studentInfo.setGrade(grade);
studentInfo.setClass_(class_);
studentInfoList.add(studentInfo);
// do something useful with these
cursor.moveTonext();
}
cursor.close();
}
public void close() {
SQLiteDatabase db = this.getReadableDatabase();
db.close();
}
public ArrayList
if (this.studentInfoList.size() == 0) {
this.queryAll();
}
return this.studentInfoList;
}
}
- 新建一个名为RemoveServiceClient的项目,做为调用远程Service的工程
把RemoteServiceServer中创建的aidl拷贝到RemoveServiceClient项目中,
并将StudentInfo,RemoteServiceServer对应的目录下,在RemoveServiceClient代码目录生成同样的目录,并拷贝StudentInfo在当前目录下
- 在RemoveServiceClient的MainActivity中创建一个服务连接
private IMyAidlInterface myService = null;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myService = IMyAidlInterface.Stub.asInterface(service);
try {
myService.AIDL_Service();
MainActivity.this.setData();
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
在MainActivity的OnCreate中创建并绑定远程服务
if (myService == null) {
//通过Intent指定服务端的服务名称和所在包,与远程Service进行绑定
//参数与服务器端的action要一致,即"服务器包名.aidl接口文件名"
Intent intent = new Intent("com.dlrj.remoteserviceserver.IMyAidlInterface");
//Android5.0后无法只通过隐式Intent绑定远程Service
//需要通过setPackage()方法指定包名
intent.setPackage("com.dlrj.remoteserviceserver");
//绑定服务,传入intent和ServiceConnection对象
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
这样,使用远程Service,并在Service中使用Sqlite保存数据的示例就好了。



