首先声明:具体思路有借鉴一些其他人的CSDN博客...
目标:了解Android Service的具体流程
实现方法:通过创建一个简单的Service例子,了解Service生命周期
所学到的知识:
1.如果Service等的AndroidManifest中声明为android:exported="false"
则该服务不能够跨进程使用。
2.Service流程为 onCreate()-onStartCommand()-onStart()-stopService()-onDestroy()
或者onCreate()-onBind()-unbindService()-onDestroy()
3.stopService(new Intent(ServiceDemo.ACTION))并不能停止服务
必须使用this.stopService(new Intent(ServiceDemo.ACTION))//可能是需要上下文的缘故
4.如果是onBind创建的Service,之后执行stopService()不会有任何反应,但是可以执行onStartCommand()和onStart(),但是之后不是通过stopService()关闭而是程序退出时自动关闭(onBind在起作用)
5.如果是onStart()创建的Service,之后可以执行onBind(),退出程序时会自动关闭(相当于是onBind()在起作用而不是onStart()在起作用),但是onStart()-onBind()后,stopService()不再起作用。
6.如何判断Service已经绑定,设置一个boolean变量,bindService是设为真,Unbind时设为假(因为退出Activity时必须判断,如果已经绑定了Service才会执行unbindService(),要不然会报错)
7.若是.xml的线性布局里面将Button放在了最上面,manifest里面必须设置android:theme="@android:style/Theme.NoTitleBar.Fullscreen",否则会出错(估计是因为标题将button的位置给占用了,两个widget冲突所致)
8.资源文件里面的名字要使用小写,如果使用大小会报错.
具体步骤:
1.创建Android工程(不使用默认的Activity,自己手动创建)名称:Test02_Service_dlc,包名:dlc.test02.service
2.在dlc.test02.service.utils里面创建一个Attributes类(该类的作用是定义一些全局参数变量,例如屏幕的宽高)
3.在dlc.test02.service包里面创建一个SplashActivity类(该类的作用是一个Splash界面,并在里面初始化各种必须的全局数据),里面通过Handler将开启MainActivity的线程post到主消息队列中,然后再关闭SplashActivity,所以最后的结果就是主线程只有MainActivity.
4.在dlc.test02.service包里面创建一个MainActivity类(该类里面有一些跳转按钮,分别对应各种不同的Service练习,本次加了一种)
5..在dlc.test02.service包里面创建一个ServiceDemo类(该类是一个Service类,里面的重写函数Log一些消息)
7.在AndroidManifest里面进行配置
9.开始给各自的类里面填充相应的功能
至此,整个APP就完成了!
主要就是重写了很多函数,分别Log消息出来检测。
以下是具体代码:
Attributes.java
package dlc.test02.service.utils;
public class Attributes {
public static int screenWidth;
public static int screenHeight;
}
package dlc.test02.service;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.util.Log;
import dlc.test02.service.utils.Attributes;
public class SplashActivity extends Activity{
private static final String TAG="SplashActivity";
/**创建*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
/**通过Handler,将一个线程放入主消息队列中*/
Log.i(TAG,"将MainActivity线程推入主消息队列");
Handler x=new Handler();
x.postDelayed(new splashHandler(), 2000);
}
/**功能函数*/
private void initialAttributes()
{
//初始化屏幕宽高
DisplayMetrics dm=new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
Attributes.screenWidth=dm.widthPixels;
Attributes.screenHeight=dm.heightPixels;
}
/**内部线程类,开启主Activity*/
private class splashHandler implements Runnable{
@Override
public void run() {
initialAttributes();
//开启主界面,显示调用
startActivity(new Intent(getApplication(),MainActivity.class));
//关闭Splash界面
Log.i(TAG,"关闭SplashActivity");
SplashActivity.this.finish();
}
}
}
package dlc.test02.service;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener{
private static final String TAG="MainActivity";
private Button btn_startServiceDemo;
/**创建*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置View
setContentView(R.layout.main);
btn_startServiceDemo=(Button) findViewById(R.id.btn_startServiceDemo);
btn_startServiceDemo.setOnClickListener(this);
}
//这个方法,一定得需要类实现OnClickListener接口
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn_startServiceDemo:
onStartServiceDemo();
break;
default:
break;
}
}
/**功能函数*/
private void onStartServiceDemo()
{
Log.i(TAG, "点击启动ServiceDemo按钮");
//开启ServiceDemoActivity界面
startActivity(new Intent(getApplication(),ServiceDemoActivity.class));
}
}
package dlc.test02.service;
import android.app.Service;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
public class ServiceDemo extends Service{
private static final String TAG="ServiceDemo";
//Service对应的Action属性,与Manifest里面配置的一致
public static final String ACTION="dlc.test02.service.ServiceDemo";
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG,"ServiceDemo onBind");
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG,"ServiceDemo onCreate");
}
@Override
@Deprecated
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i(TAG,"ServiceDemo onStart");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG,"ServiceDemo onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void unbindService(ServiceConnection conn) {
super.unbindService(conn);
Log.i(TAG,"ServiceDemo unbindService");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG,"ServiceDemo onDestroy");
}
}
package dlc.test02.service;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ServiceDemoActivity extends Activity implements OnClickListener{
private static final String TAG="ServiceDemoActivity";
//是否绑定Service的标识
private boolean isBindService=false;
//按钮对象
private Button btn_bindService;
private Button btn_startService;
private Button btn_stopService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.service_demo_view);
initialButtons();
registListener();
}
@Override
protected void onDestroy() {
Log.v(TAG, "onDestroy unbindService");
//如果已经绑定了Service,则退出时解绑
if(isBindService)
{
unbindService(conn);
isBindService=false;
}
super.onDestroy();
}
//所有按钮监听的集合
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn_bindService:
onBindService();
break;
case R.id.btn_startService:
onStartService();
break;
case R.id.btn_stopService:
onStopService();
break;
default:
break;
}
}
/**功能函数*/
//初始化按钮
private void initialButtons()
{
btn_bindService=(Button) findViewById(R.id.btn_bindService);
btn_startService=(Button) findViewById(R.id.btn_startService);
btn_stopService=(Button) findViewById(R.id.btn_stopService);
}
//设置按钮监听
private void registListener()
{
btn_bindService.setOnClickListener(this);
btn_startService.setOnClickListener(this);
btn_stopService.setOnClickListener(this);
}
/**两种不同的启动Service的方式*/
private void onBindService()
{
Log.i(TAG, "点击启动bindService按钮");
bindService(new Intent(ServiceDemo.ACTION), conn, BIND_AUTO_CREATE);
isBindService=true;
}
private void onStartService()
{
Log.i(TAG, "点击启动startService按钮");
startService(new Intent(ServiceDemo.ACTION));
}
private void onStopService()
{
Log.i(TAG, "点击stopService按钮");
//由于Android的原理是只有一个Service,所以可以这么使用,它不会创建,而是得到原来的那个Service
this.stopService(new Intent(ServiceDemo.ACTION));
}
/**服务器连接*/
ServiceConnection conn=new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "onServiceConnected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "onServiceDisconnected");
}
};
}
Test02_Service_dlc
打开ServiceDemo
绑定服务
启动服务
停止服务