您的位置:首页 > 移动开发 > Android开发

android Service

2016-03-01 20:03 417 查看

service生命周期

service的生命周期跟启动服务的方法有关:

1.当采用Context.startService()方法启动服务,与之有关的生命周期方法:

onCreate()->onStartCommand()->onDestroy()

onCreate():服务被创建时调用,只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。

onStartCommand():只有采用Context.startService()方法启动服务时才会回调该方法。在服务开始运行时被调用,多次调用startService()方法尽管不会多次创建服务,但onStart()会被多次调用。

onDestroy():该方法在服务被终止时调用.

2.当采用Context.bindService()方法启动服务,与之有关的生命周期方法:

onCreate()->onBind()->onUnbind()->onDestroy()

onBind()::只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法不会导致该方法被多次调用。

onUnbind()方法:只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。

3.如果先采用startService()方法启动服务,然后调用bindService()方法绑定服务,再调用unbindService()方法解除绑定,最后调用bindService()方法再次绑定到服务,触发的生命周期方法如下:

onCreate()->onStartCommand()->onBind()->onUnbind()[重载后的方法需返回true]->onRebind();

简单的说就是onCreate()->onStart()->onDestroy()

Activity中和service有关的方法:

startService(Intent intent):启动一个service

stopService(Intent intent) :停止一个service

如果我们想使用service中的一些数据或者访问其中的一些方法,那么我们就要通过下面的方法:

public boolean bindService(Intent intent, ServiceConnection conn, int flags) ;

public void unbindService(ServiceConnection conn);

intent是跳转到service的intent,如 Intent intent = new Intent(); intent.setClass(this,MyService.class);

conn则是一个代表与service连接状态的类,当我们连接service成功或失败时,会主动触发其内部的onServiceConnected或onServiceDisconnected方法。如果我们想要访问service中的数据,可以在onServiceConnected()方法中进行实现.

## 标题 ##

使用service基本步骤

第一步:继承service类,实现自己的service

public class MyConService extends Service {}//继承service


第二步:

在androidManifest.xml中的节点里对服务进行配置进行注册,如:

<application android:xxx=xxx>
<!-- service配置开始 -->
<service android:name="MyService"></service>
<!-- service配置结束-->
</application>


第三步:在activity中进行启动、绑定、解绑或者停止service。

服务不能自己运行,需要通过调用Context.startService()或Context.bindService方法启动服务。这两个方法都可以启动服务,但是它们的使用场合不同。

使用startService()方法启动服务,访问者与服务之间没有关联,即使访问者退出了,服务仍然运行。

使用bindService()方法启动服务,访问者和服务绑定在了一起,访问者一旦退出,服务也就终止,大有“不求同时生,但求同时死”的特点。

采用Context.startService()方法启动服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。

有关service的例子

控制手机振动

public class VibratorTest extends Activity {
Vibrator vibrator;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//获取到系统的震动服务
vibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
Toast.makeText(this, "phone is vibrator", Toast.LENGTH_LONG).show();
vibrator.vibrate(2000);//震动指定时间,数据类型long,单位为毫秒,一毫秒为1/1000秒
return super.onTouchEvent(event);
}
}


记得要在AndroidManifest.xml里面添加权限,否则会出错

//最重要的,增加权限,否则运行时出错
<uses-permission android:name="android.permission.VIBRATE"/>


获取网络和SIM卡信息

public class TelephonyStatus extends Activity {
ListView ShowView;
String[] statusnames; //声明代表状态名的数组
ArrayList<String> statusvalues = new ArrayList<String>(); //声明代表手机状态的集合

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

TelephonyManager telephonyManager = (TelephonyManager)
getSystemService(TELEPHONY_SERVICE);// 获取系统的TelephonyManager对象
statusnames = getResources().getStringArray(R.array.statusNames);//获取各种状态名称的数组
String[] simState = getResources().getStringArray(R.array.simState);//获取代表SIM卡状态的数组
String[] phoneType = getResources().getStringArray(R.array.phoneType);// 获取代表电话网络类型的数组
statusvalues.add(telephonyManager.getDeviceId());// 获取设备编号
statusvalues.add(telephonyManager.getDeviceSoftwareVersion() != null ? telephonyManager
.getDeviceSoftwareVersion() : "未知");// 获取系统平台的版本
statusvalues.add(telephonyManager.getNetworkOperator());// 获取网络运营商代号
statusvalues.add(telephonyManager.getNetworkOperatorName());// 获取网络运营商名称
statusvalues.add(phoneType[telephonyManager.getPhoneType()]);// 获取手机网络类型
statusvalues.add(telephonyManager.getCellLocation() != null ? telephonyManager
.getCellLocation().toString() : "未知位置");// 获取设备所在位置
statusvalues.add(telephonyManager.getSimCountryIso());// 获取SIM卡的国别
statusvalues.add(telephonyManager.getSimSerialNumber());// 获取SIM卡序列号
statusvalues.add(simState[telephonyManager.getSimState()]);// 获取SIM卡状态
ShowView = (ListView) findViewById(R.id.show);// 获得ListView对象
ArrayList<Map<String, String>> status = new ArrayList<Map<String, String>>();
// 遍历statusValues集合,将statusNames、statusValues
// 的数据封装到List<Map<String , String>>集合中
for (int i = 0; i < statusvalues.size(); i++)
{
HashMap<String, String> map = new HashMap<String, String>();
map.put("name", statusnames[i]);
map.put("value", statusvalues.get(i));
status.add(map);
}
// 使用SimpleAdapter封装List数据
SimpleAdapter adapter = new SimpleAdapter(this, status,
R.layout.line, new String[] { "name", "value" }
, new int[] { R.id.name, R.id.value });
// 为ListView设置Adapter
ShowView.setAdapter(adapter);
}


定时自动切换壁纸

在写这个小demo时候,首先必须要知道AlarmManager.RTC和ELAPSED_REALTIME的区别,网上搜索一下,

AlarmManager.RTC,硬件闹钟,不唤醒手机(也可能是其它设备)休眠;当手机休眠时不发射闹钟。

AlarmManager.RTC_WAKEUP,硬件闹钟,当闹钟发躰时唤醒手机休眠;

AlarmManager.ELAPSED_REALTIME,真实时间流逝闹钟,不唤醒手机休眠;当手机休眠时不发射闹钟。

AlarmManager.ELAPSED_REALTIME_WAKEUP,真实时间流逝闹钟,当闹钟发躰时唤醒手机休眠;

RTC闹钟和ELAPSED_REALTIME最大的差别就是前者可以通过修改手机时间触发闹钟事件,后者要通过真实时间的流逝,即使在休眠状态,时间也会被计算。

alarmManager.setRepeating(type, triggerAtMillis, intervalMillis, operation)

功能:该方法用于设置重复闹钟,第一个参数表示闹钟类型,第二个参数表示触发这个闹钟要等待的时间,第三个参数表示闹钟两次执行的间隔时间,第三个参数表示闹钟响应动作。

PendingIntent: Intent的封装包,简单的说就是在Intent上在加个指定的动作。在使用Intent的时候,我们还需要在执行startActivity、startService或sendBroadcast才能使Intent有用。而PendingIntent的话就是将这个动作包含在内了。

eg.

//定义一个PendingIntent对象,此处先照样画葫芦
PendingIntent pi = PendingIntent.getBroadcast(Context, int, Intent, int);
PendingIntent pi = PendingIntent.getService(AlarmChangeWallpaper.this, 0, intent, 0);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: