服务Service

  1. 服务(Service)是Android中实现程序后台运行的解决方案,适合执行不需要和用户交互且需长期运行的任务,不依赖于任何用户界面。
  2. 服务并不是运行在一个独立进程中,依赖于创建服务时所在的应用程序进程(应用程序被杀掉,服务也会停止运行),默认在主线程中运行(一般在内部手动创建子线程)。
  3. Android多线程
    (1)线程基本用法:
    新建继承自Thread的类定义一个线程,重写父类的run()方法,通过new出此类的实例,调用其start()方法来启动:
    new MyThread().start();
    使用实现Runnable接口的方式定义一个线程(使用集成的方式耦合性有点高,更多采用此方法)
    MyThread myThread = new MyThread();
    new Thread(myThread).start;//Thread的构造函数接收一个Runnable参数
    (2)在子线程中更新UI
    Android的UI是线程不安全的,必须在主线程中更新UI元素,否则会出现异常。但有时必须在子线程中执行一些耗时任务,根据结果更新相应UI元素,因此,Android提供异步消息处理机制。
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<Button
    android:id="@+id/change_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Change Text"/>
    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Hello World!"
        android:textSize="20sp" />
</LinearLayout>
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView text;
public static final int UPDATE_TEXT=1;
//定义一个常量UPDATE——TEXT,用于表示更新textView这个动作
//新增一个Handler对象,重写handleMessage()方法
private Handler handler=new Handler(){
    public void handleMessage(Message msg) {
        switch (msg.what){
            case UPDATE_TEXT:
                //在这里进行UI操作
                text.setText("How are you?");
                break;
            default:
                break;
        }
    }
};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text=(TextView) findViewById(R.id.text);
        Button chaneText = (Button) findViewById(R.id.change_text);
        chaneText.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
switch (view.getId()){
    case  R.id.change_text:
        new Thread(new Runnable() {
            @Override
            public void run() {
                //创建了Message(android.os.Message)对象
                Message message=new Message();
                message.what=UPDATE_TEXT;
                handler.sendMessage(message);//将Message对象发送出去
            }
        }).start();
        break;
    default:
        break;
}
    }
}

新建一个Handler对象,重写handleMessage(Message msg)方法
在线程run()中创建Message对象,设置what属性的 值,利用Hander对象sendMessage(message)发送
(3)异步消息处理机制
Android中的异步消息处理主要由4部分组成:

	Message:在线程之间传递的消息,可在内部携带少量信息,用在不同的线程之间交换数据。有what字段、arg1/arg2字段(携带整型数据)、obj字段(携带Object对象)。
	Handler:处理者,用于发送和处理消息。发送消息一般使用Handler的sendMessage()方法,发出的消息经系列辗转处理后传递到Handler的handleMessage()方法中。
	MessageQueue:消息队列,用于存放所有通过Handler发送的消息。这部分的消息一直存在于消息队列中,等待被处理。每个线程只有一个MessageQueue对象。
	Looper:每个线程中MessageQueue的管家,调用Looper的loop()方法后会进入到无限循环中,每当发现MessageQueue中存在一条消息就取出,并传递到Handler的handleMessage()方法中。每个线程只有一个Looper对象。
   异步消息处理流程:在主线程中创建一个Handler对象并重写handleMassage()方法;当子线程中需进行UI操作时,创建一个Message对象并通过Handler发送这条消息;此消息会被添加到MessageQueue队列中等待被处理,Looper一直尝试从MessageQueue中取出待处理消息,后分发回Handler的handleMessage()中。由于Handler在主线程中创建,所以相应的handleMessage()方法中的代码也在主线程中运行,可在此进行UI操作(消息从子线程进入主线程)。 
  1. 使用AsyncTask
    AsyncTask是一个抽象类,需创建子类继承。继承时可指定三个泛型参数:
    Params:在执行AsyncTask时需传入的参数,可用于在后台任务中使用
    Progress:后台任务执行时,如需在界面上显示当前进度,则使用此泛型单位
    Result:任务执行完毕后,如需返回结果,则使用此泛型作为返回值类型
class DownloadTask extends AsyncTask<Void,Integer,Boolean>{...}
	Params设置为Void,表示在执行AsyncTask时,不需要传入参数给后台任务
	Progress设置为Integer,表示使用整形数据作为进度显示的进度单位
	Result设置为Boolean表示使用布尔类型的数据来反馈执行的结果

需要重写的方法:
onPreExecute()
这个方法会在后台任务开始执行之前调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框等。
doInBackground(Params…)
这个方法的所有代码都会在子线程中运行,不会影响主线程,我们在这处理所有的耗时任务。
任务一旦完成,通过return返回结果,Rusult指定为Void则不返回结果,这个方法中不能进行UI操作,如需更新UI,可调用publishProgress(Progress…)完成;
onProgressUpdate(Progress…)
当后台调用publishProgress后,会被很快调用,参数是后台任务中传递过来的,可利用参数操作UI,进行更新;
onPostExecute(Result)
主线程中运行。后台任务完成并通过return返回时很快被调用,可利用返回的数据进行UI操作,如提醒执行结果、关闭进度条等
5. 服务的生命周期
onCreate()第一次创建的时候调用
onStartCommand()每次启动服务的时候调用
onDestroy()服务销毁时调用
服务需要注册。
布局文件MainActivity,加入两个按钮分别启动和停止服务

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/start_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Service"/>
    <Button
        android:id="@+id/stop_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Stop Service"/>
</LinearLayout>

新建ServiceTest项目,右键包名New一个Service,Exported(是否允许除了当前的程序之外其它的程序访问这个服务)和Enableed(是否启动这个服务):

public class MyService extends Service {
    public MyService() {
    }
    @Override
//唯一一个抽象方法
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService","onCreate executed");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService","onStartCommand executed");
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyService","onDestroy executed");
    }
}
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startService = (Button) findViewById(R.id.start_service);
        Button stopService = (Button) findViewById(R.id.stop_service);
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.start_service:
                Intent startIntent = new Intent(this, MyService.class);
                startService(startIntent);//启动服务,startService定义在Context类中
                break;
            case R.id.stop_service:
                Intent stopIntent = new Intent(this, MyService.class);
                stopService(stopIntent);//停止服务,stopService定义在Context类中
                break;
            default:
                break;
        }
    }
}
  1. 活动和服务之间的通信:
    借助onBind()方法,在活动中控制服务。
    希望在MyService里提供一个下载功能,在活动中可以决定何时开始下载及随时查看下载进度。
    创建一个专门的Binder对象管理下载功能,修改MyService:
public class MyService extends Service {
    private DownloadBinder mBinder=new DownloadBinder();
    class DownloadBinder extends Binder{
        public void startDownload(){
            Log.d("MyService","startDownload executed");
        }
        public int getProgress(){
            Log.d("MyService", "getProgress executed");
            return 0;
        }
    }
    public MyService() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return mBinder;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService","onCreate executed");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.d("MyService","onStartCommand executed");
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyService","onDestroy executed");
    }
}

修改MainActivity

	public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private MyService.DownloadBinder downloadBinder;
private ServiceConnection connection=new ServiceConnection() {
    //活动与服务绑定时调用
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
          downloadBinder=(MyService.DownloadBinder) service;
          downloadBinder.startDownload();
          downloadBinder.getProgress();
    }
    //活动与服务解除绑定时调用
    @Override
    public void onServiceDisconnected(ComponentName componentName) {

    }
};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startService = (Button) findViewById(R.id.start_service);
        Button stopService = (Button) findViewById(R.id.stop_service);
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
        Button bindService = (Button) findViewById(R.id.bind_service);
        Button unbindService = (Button) findViewById(R.id.unbind_service);
        bindService.setOnClickListener(this);
        unbindService.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.start_service:
                Intent startIntent = new Intent(this, MyService.class);
                startService(startIntent);//启动服务,startService定义在Context类中
                break;
            case R.id.stop_service:
                Intent stopIntent = new Intent(this, MyService.class);
                stopService(stopIntent);//停止服务,stopService定义在Context类中
                break;
            case R.id.bind_service:
                Intent bindIntent = new Intent(this, MyService.class);
                bindService(bindIntent, connection, BIND_AUTO_CREATE);
                //绑定服务,第一个参数为intent,第二个参数为创建的ServiceConnection对象,第三个参数为标志位,
                // BIND_AUTO_CREATE表示在活动与服务绑定后自动创建服务:onCreate()方法执行而onStartCommand()方法不执行
                break;
            case R.id.unbind_service:
                unbindService(connection);//解绑服务
                break;
            default:
                break;
        }
    }
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/start_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Service"/>
    <Button
        android:id="@+id/stop_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Stop Service"/>
    <Button
        android:id="@+id/bind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Bind Service"/>
    <Button
        android:id="@+id/unbind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Unbind Service"/>
</LinearLayout>

bindService(bindIntent, connection, BIND_AUTO_CREATE);
//绑定服务,第一个参数为intent,第二个参数为创建的ServiceConnection对象,第三个参数为标志位,
// BIND_AUTO_CREATE表示在活动与服务绑定后自动创建服务:onCreate()方法执行而onStartCommand()方法不执行
unbindService(connection);
//解绑服务
7. 服务
一旦调用了Context的startService(),
服务启动并回调onStartCommand()方法(没没创建则先执行onCreate()方法);
直到stopService()/stopSelf()被调用。
每个服务只存在一个实例,只需调用一次stopService()/stopSelf()就会停止。

另,调用Context的bindService()获取服务的持久连接,
同时会回调服务中的onBind()方法(服务之前没创建则先调用onCreate()方法)。
调用方可获取onBind()返回的IBinder对象实例,与服务进行自由通信。
只要连接没断开,服务会一直保持运行。
当调用了startService()/bindService()后,对应调用stopService()/unbindService(),onDestroy()会被执行。若startService()和bindService()都调用,那么stopService()/unbindService()均要调用才可onDestroy()。

服务只要被启动或被绑定,就会一直处于运行状态,必须同时不满足以上两种条件才能被销毁。所以,如果对服务既调用了startService()又调用了bindService(),要同时调用stopService()和unbindService()方法,onDestroy()才会被执行。
8. 前台服务
@Override
public void onCreate() {
super.onCreate();
Log.d(“MyService”,“onCreate executed”);
Intent intent=new Intent(this, MainActivity.class);
PendingIntent pi=PendingIntent.getActivity(this,0,intent,0);
NotificationChannel channel = new NotificationChannel(“channel_1”, “123”, NotificationManager.IMPORTANCE_HIGH);//生成channel
Notification notification=new NotificationCompat.Builder(this,“channel_1”)
.setContentTitle(“This is content title”)
.setContentText(“This is content”)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.setContentIntent(pi)
.build();
startForeground(1,notification);
//startForeground让MyService成为一个前台服务,并在系统状态栏显示
}
9. 使用IntentService
服务的代码默认在主线程中运行,如果直接在服务里去处理一些耗时的逻辑,就很容易出现ANR(Application Not Responding),因此需要多线程编程,一个比较标准的服务:
public MyService extends Service{
@Override
public int onStartCommand(Intent intent,int flagd,int startId){
new Thread(new Runnable(){
@Override
public void run(){
//具体的逻辑在这里

}
}).start();
return super.onStsrtCommand();
}
}
10.服务中代码默认在主线程中运行,所以应该在服务每个具体方法里开启一个子线程去处理耗时操作,要让服务自动停止还需调用stopSelf()方法。为了简单创建一个异步自动停止的服务,Android专门提供了一个IntentService类。
新建一个MyIntentService类继承自IntentService:

public class MyIntentService extends IntentService {
    public MyIntentService(){
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.d("MyIntentService","Thread id is"+Thread.currentThread().getId());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyIntentService","onDestroy executed");
    }
}
protected void onCreate(Bundle savedInstanceState) {
...
 Button startIntentService = (Button) findViewById(R.id.start_intent_service);
        startIntentService.setOnClickListener(this);
}
public void onClick(View v) {
        switch (v.getId()){
...
case R.id.start_intent_service:
                //打印主线程id
                Log.d("MainActivity", "Thread id is " + Thread.currentThread().getId());
                Intent intentService = new Intent(this, MyIntentService.class);
                startService(intentService);
                break;
default:
                break;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Activiti7是一个基于Spring Boot的开源工作流引擎,它提供了一系列的服务来支持工作流的实现。其中,大服务(Service)是Activiti7中的一种重要的服务类型,它承担了很多核心功能。下面我们来详细介绍一下Activiti7大服务的各种类型及其作用。 1. Identity Service Identity Service是Activiti7中的一个重要服务,它提供了用户和组的管理功能。通过Identity Service,我们可以创建、删除、更新用户和组,以及查询用户和组的信息。在Activiti7中,用户和组是与任务和流程实例相关联的,因此Identity Service对于工作流的实现非常关键。 2. Runtime Service Runtime Service是Activiti7中的另一个重要服务,它提供了流程实例的管理功能。通过Runtime Service,我们可以启动、暂停、恢复、删除流程实例,以及查询流程实例的状态。在Activiti7中,每个流程实例都有一个唯一的标识符,我们可以通过Runtime Service来管理这些流程实例。 3. Task Service Task Service是Activiti7中的一个重要服务,它提供了任务的管理功能。通过Task Service,我们可以创建、完成、删除任务,以及查询任务的信息。在Activiti7中,任务是流程实例中的一个环节,它需要被分配给具体的用户或组去执行。 4. Form Service Form Service是Activiti7中的一个服务,它提供了表单的管理功能。通过Form Service,我们可以查询、创建、更新和删除表单。在Activiti7中,表单是与任务和流程实例相关联的,它可以用来展示和收集用户输入的数据。 5. History Service History Service是Activiti7中的一个服务,它提供了历史数据的管理功能。通过History Service,我们可以查询已经完成的流程实例、任务和变量的历史数据。在Activiti7中,历史数据包括流程实例的启动时间、结束时间,任务的创建时间、完成时间,以及变量的修改历史等信息。 6. Management Service Management Service是Activiti7中的一个服务,它提供了管理功能。通过Management Service,我们可以查询Activiti7的配置信息,管理数据库表,以及执行一些系统级别的操作。在Activiti7中,Management Service需要有管理员权限才能使用。 总之,Activiti7大服务是Activiti7引擎的核心组成部分,它提供了许多重要的功能,包括用户和组的管理、流程实例的管理、任务的管理、表单的管理、历史数据的管理以及管理功能等。这些服务使得Activiti7成为了一个功能强大、易于使用的工作流引擎。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值