目录
一.本文章要学习的内容
二.代码部分
(一)创建项目
(二)如何创建文件
(三)项目结构
(四)MainActivity
(五)MyService
(六)activity_main.xml
三.运行部分
(一)打开Device Manager
(二)选择上次创建的虚拟机(具体见博主第一篇发布的Android文章)
(三)运行
(四)运行结果
四.Service
(一)概念
1.作用
2.Service与Activity的区别
3.Service的特点
(二)Service分类
1、Started Service
2、Bound Service
(三)启动Service回调的方法
1.startService():启动服务
2.bindService():绑定服务
3.onCreate():创建服务
4.onStartcommand():重复开始服务
5.onBind():绑定服务
6.unbindService():解绑服务【相对于某个组件来说】
7.onUnbind()回调函数。
8.onUnbind():解绑服务【相对于服务来说】
9.onDestroy():销毁服务
10.stopService():结束服务
11.stopSelf():结束服务
一.本文章要学习的内容
1.充分理解Service的作用,与Activity之间的区别,掌握Service的生命周期以及对应函数,了解Service的主线程性质;
2.掌握主线程的界面刷新的设计原则,掌握启动service的方式,及其工作原理;
任务1:在service中实现随机数产生;
任务2:在Activity界面实现随机数的显示,并采用启动式完成service的启动
1、在service中实现随机数产生;
2、实现Service中的各个生命周期函数,并理解其功能;
2、在Activity界面实现随机数的显示,每2秒更新一次;
3、采用启动式完成service的启动;
二.代码部分
(一)创建项目
(二)如何创建文件
在java文件夹下的com.example.demo包下右键新建Service里的Service
(三)项目结构
(四)MainActivity
通过启动式 创建Service,点击开始后调用Intent以显式 的方式调用:MyService.Java 当点击开始按钮时,调用startService(serviceIntent);方法启动service,
package com.example.demo3;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.example.demo3.R;
public class MainActivity extends AppCompatActivity {
private static Handler handler = new Handler();
private static TextView labelView = null;
private static double randomDouble;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
labelView = (TextView) findViewById(R.id.randomname);
Button start = (Button) findViewById(R.id.startrandom);
Button stop = (Button) findViewById(R.id.stoprandom);
final Intent serviceIntent = new Intent(MainActivity.this, MyService.class);
start.setOnClickListener(new Button.OnClickListener() {
public void onClick(View view) {
startService(serviceIntent);
}
});
stop.setOnClickListener(new Button.OnClickListener() {
public void onClick(View view) {
stopService(serviceIntent);
}
});
}
/**
* UpdateGUI是共有的界面更新函数,后台线程通过调用该函数,将后台产生的数据refreshDouble传递到这个函数内部
* POST -- 将Runnable对象传递给界面线程的消息队列
*
* @param refreshDouble
*/
public static void UpdateGUI(double refreshDouble) {
randomDouble = refreshDouble;
handler.post(RefreshLable);
}
/**
* Runnable对象中需要重载的run()函数,界面更新的代码在这里
*/
private static Runnable RefreshLable = new Runnable() {
@Override
public void run() {
labelView.setText(String.valueOf(randomDouble));
}
};
}
(五)MyService
调用进程:workThread = new Thread(null,backgroundWork,"WorkThread"); 以2000ms为周期生成随机数 调用其中使用方法:UpdateGUI() 将生成的随机数抛到Lopper队列中,直到Runnable对象中的 run() 方法被调用,从而使随机数 回显到原来的文本框中。
package com.example.demo3;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import androidx.annotation.Nullable;
public class MyService extends Service {
private Thread workThread;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("onCreate");
//线程组,需要执行的Runnable对象,线程的名称
workThread = new Thread(null,backgroundWork,"WorkThread");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
if(!workThread.isAlive()){
System.out.println("onStart");
workThread.start();
}
}
@Override
public void onDestroy() {
super.onDestroy();
workThread.interrupt();
}
private Runnable backgroundWork = new Runnable() {
@Override
public void run() {
try {
while(!Thread.interrupted()){
double random = Math.random();
System.out.println(random);
MainActivity.UpdateGUI(random);
Thread.sleep(2000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
(六)activity_main.xml
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.demo3.MainActivity"> android:layout_width="match_parent" android:layout_height="wrap_content" android:text="随机数:" android:textSize="20sp" /> android:id="@+id/randomname" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20sp" /> android:layout_width="377dp" android:layout_height="80dp" android:orientation="vertical" >
三.运行部分
(一)打开Device Manager
(二)选择上次创建的虚拟机(具体见博主第一篇发布的Android文章)
(三)运行
(四)运行结果
四.Service
(一)概念
Service是Android的四大组件之一。
1.作用
后台长期处理耗时的逻辑。
2.Service与Activity的区别
不同点:Service与Activity功能大抵相同,区别在于Service不存在UI界面,Service在后台运行,不能与用户进行交互功能。
相同点:都需要在清单文件中注册,且都有生命周期。
3.Service的特点
(1)、在后台运行,即使应用退出,也不会停止服务,只有在杀死APP进程时,才会停止服务。
(2)、Service运行在主线程中。所以,当我们执行一些耗时的操作时,可以在服务中创建子线程来处理耗时的操作。
(3)、Service应用广泛,例如:音乐播放,下载文件等。
(二)Service分类
按照启动方式可以分为:
1、Started Service
当组件通过调用 startService() 方法启动 Service ,这时,Service处于启动状态,可以在后台无限期的运行,只有自身调用stopSelf() 方法 或者 其他组件调用 stopService() 方法才会停止Service。
2、Bound Service
当组件通过调用 bindService() 方法绑定 Service,这时,Service处于绑定状态,多个组件可以绑定在一个Service上,当绑定Service的所有组件解绑之后,该Service被销毁。
两种启动方式的生命周期如下:
(三)启动Service回调的方法
1.startService():启动服务
(手动调用)不受调用组件的控制,可以在后台无限期的运行。
2.bindService():绑定服务
(手动调用)将多个组件与服务绑定在一块,随着组件的消亡而消亡。
3.onCreate():创建服务
(自动调用)无论是开启服务还是绑定服务,最开始的回调函数肯定是onCreate(),当第一次创建Service的时候调用该方法,多次调用startService()方法不会重复调用onCreate() 方法。适合做一些初始化操作。
4.onStartcommand():重复开始服务
(自动调用)当多次执行startService()方法的时候,onStartcommand()都会执行。
5.onBind():绑定服务
(自动调用)当一个组件想要通过bindService()绑定service时,系统会回调该方法。该方法需要实现一个接口,通过返回IBinder对象实现用户通信。若不需要绑定service则返回null,否则必须实现。
6.unbindService():解绑服务【相对于某个组件来说】
(手动调用)当组件想要与该服务解绑时调用,只有在所有用户解绑之后才会调用
7.onUnbind()回调函数。
8.onUnbind():解绑服务【相对于服务来说】
(自动调用)当所有捆绑服务的组件解绑之后,系统自动调用onUnbind()函数,将服务解绑。
9.onDestroy():销毁服务
(自动调用)当Service调用这个函数的时候,这个服务就销毁停止了。下次在用的时候只能执行onCreate()函数进行创建。
10.stopService():结束服务
(手动调用)其他组件通过调用该函数,将以startService()启动的Service停止掉。
11.stopSelf():结束服务
(手动调用)当前Service调用此方法来终结自己。
评论留言