四大组件之service简单介绍和AIDL的简单使用

Service是什么

1.Service是一个应用组件, 它用来在后台完成一个时间跨度比较大的工作且没有关联任何界面

2.一个Service可以完成下面这些工作:

访问网络
播放音乐
文件IO操作
大数据量的数据库操作
……

3. 服务的特点:

Service在后台运行,不用与用户进行交互

即使应用退出, 服务也不会停止.

在默认情况下,Service运行在应用程序进程的主线程(UI线程)中,如果需要在Service中处理一些网络连接等耗时的操作,那么应该将这些任务放在分线程中处理,避免阻塞用户界面

区别Service与Activity?

Activity:

Activity对应一个界面

应用退出, Activity对象就会死亡

应用再次进入, 启动的Activity对象是重新创建的

2. Service

不与任何界面关联

应用退出, Service仍在运行

应用再次进入, 启动的Service还是前面运行的Service对象

Service的分类

1.Local Service(本地服务)

Service对象与Serive的启动者在同个进程中运行, 两者的通信是进程内通信

2.Remote Service(远程服务)

Service对象与Service的启动者不在同一个进程中运行, 这时存在一个进程间通信的问题, Android专门为此设计了AIDL来实现进程间通信

使用本地服务

定义service

1.定义一个类继承于Service类
   public class MyService extends Service {

   }
在AndroidManifest.xml中配置Service
 <service android:name=".test.MyService">
     <intent-filter>
      <action android:name="com.atguigu.service.test.MyService" />
     </intent-filter>
    </service>

启动与停止Service

方式一 : 一般启动与停止
 context.startService(Intent intent)
 context.stopService(Intent intent)
方式二 : 绑定启动与解绑
 context.bindService(Intent intent, ServiceConnection connection)
 context.unbindService(ServiceConnection connection)

Service生命周期

1.startService(intent)

第一次调用 : –>构造方法()–>onCreate()–>onStartCommand()
(重要)后面再调用 : –>onStartCommand()
stopService() : –>onDestory()

2 bindService(intent, serviceConnection)

调用 : –>构造方法()–>onCreate()–>onBind()–>onServiceConnected()
unbindService(): (中有当前Activity与Service连接)–>onUnbind()–>onDestroy()
Service生命周期

AIDL理解

每个应用程序都运行在自己的独立进程中,并且可以启动另一个应用进程的服务,而且经常需要在不同的进程间传递数据对象。

在Android平台,一个进程不能直接访问另一个进程的内存空间,所以要想对话,需要将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界。

AIDL (Android Interface Definition Language)

用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。

如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。

案例

服务器端

首先定义一个AIDL接口IStudentService.aidl,定义其中方法
package com.hbwj.myapplication.remote;
import com.hbwj.myapplication.remote.Student;

interface IStudentService {
     Student getStudentById(int id);
}

注意: import com.hbwj.myapplication.remote.Student;一定要导入本地下的aidl下的Student

定义自定义类型Student
public class Student implements Parcelable {
    private int id;
    private String name;
    private double price;

    public Student(int id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    protected Student(Parcel in) {
        this.id = in.readInt();
        this.name = in.readString();
        this.price = in.readDouble();
    }

    public static final Creator<Student> CREATOR = new Creator<Student>() {
        //解包: 读取包中的数据并封装成对象
        @Override
        public Student createFromParcel(Parcel in) {
            Log.e("TAG", "解包 createFromParcel()");
            int id = in.readInt();
            String name = in.readString();
            double price = in.readDouble();
            return new Student(id, name, price);
        }

        //返回一个指定大小的对象容器
        @Override
        public Student[] newArray(int size) {
            return new Student[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    //将当前对象的属性数据打成包: 写到包对象中
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        Log.e("TAG", "打包 writeToParcel()");
        dest.writeInt(id);
        dest.writeString(name);
        dest.writeDouble(price);
    }
}

注意: 一定要继承于Parcelable

创建文件:Student.aidl
package com.hbwj.myapplication.remote;
parcelable Student;
在Service类中使用生成的类实现业务方法
public class MyRemoteService extends Service {
    public MyRemoteService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new StudentService();
    }

    //处理Student相关的业务逻辑类
    class StudentService extends IStudentService.Stub {

        @Override
        public Student getStudentById(int id) throws RemoteException {
            //处理Student相关的业务逻辑类
            return new Student(id, "TOM", 10000);
        }
    }
}

注意:在服务器端中的manifest中需要添加注册

<service
            android:name=".remote.MyRemoteService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.hbwj.myapplication.remote.MyRemoteService.Action"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </service>
客户端

复制服务端AIDL的相关定义
Android自动生成一个通信接口类
在Activity中bind远程Service,并调用业务方法

注意: 直接复制服务器端下的AIDL所有文件,包名也一起复制过去,不能修改,否则报错

随后复制Student.java

进行客户端编码
public class MainActivity extends AppCompatActivity {
    private EditText et_aidl_id;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_aidl_id = (EditText) findViewById(R.id.et_aidl_id);

    }

    private ServiceConnection conn;
    private IStudentService studentService;

    public void bindRemoteService(View v) {
        if (conn == null) {
            Intent intent = new Intent("com.hbwj.myapplication.remote.MyRemoteService.Action");
            conn = new ServiceConnection() {
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {
                    studentService = IStudentService.Stub.asInterface(service);
                }

                @Override
                public void onServiceDisconnected(ComponentName name) {

                }
            };
            bindService(intent, conn, Context.BIND_AUTO_CREATE);
            Toast.makeText(this, "绑定Service", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "已经绑定Service", Toast.LENGTH_SHORT).show();
        }
    }

    public void invokeRemote(View v) throws RemoteException {
        if (studentService != null) {
            int id = Integer.parseInt(et_aidl_id.getText().toString());
            Student student = studentService.getStudentById(id);
            Toast.makeText(this, student.toString(), Toast.LENGTH_SHORT).show();
        }
    }

    public void unbindRemoteService(View v) {
        if (conn != null) {
            unbindService(conn);
            conn = null;
            studentService = null;
            Toast.makeText(this, "解绑Service", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "还未绑定Service", Toast.LENGTH_SHORT).show();
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值