步骤:
一般使用服务的顺序为 :
开启服务(onCreate-onStart)->绑定服务(onBind)->调用服务的方法()->解绑服务(onUnbind)->停止服务(onDestroy)
这样服务的生命周期较为可控,
注意:
- 解绑操作只可执行一次,为保证调用者退出时解绑,配合activity onDestory使用(见代码)
- 如果服务绑定过,直接stopService停不掉,必须先解绑
- 如果服务没有通过startService开启过,则解绑服务会调用onDestory()
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:orientation="vertical"
>
<Button
android:onClick="start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开启服务" />
<Button
android:onClick="stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止服务" />
<Button
android:onClick="changeSingName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="调用服务中的方法" />
<Button
android:onClick="bind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bind服务" />
<Button
android:onClick="unbind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="UnBind服务" />
</LinearLayout>
package com.example.service;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity
{
private final String TAG="ChungeService";
//步骤四、得到Binder对象引用
private IService binder;
private MyConn conn;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* 开启服务
*
* @param v
*/
public void start(View v)
{
Intent intent = new Intent(this, ChungeService.class);
// 服务对象 被系统框架实例化的(new)
startService(intent);
}
/**
* 停止服务
*
* @param v
*/
public void stop(View v)
{
Intent intent = new Intent(this, ChungeService.class);
stopService(intent);
}
/**
* 换歌 调用service中的方法
*
* @param v
*/
public void changeSingName(View v)
{
// 此方法不可行 没有android的上下文
// ChungeService chungeService=new ChungeService();
// chungeService.changeSing("name");
//利用bindService()可以间接得到服务的代理人
//步骤5、利用Binder对象间接调用服务里的方法
binder.callChangeName("月亮之上");
}
/**
* 绑定服务
* @param v
*/
public void bind(View v)
{
start(v);
Intent intent = new Intent(this, ChungeService.class);
//conn 代理人对象 不可为空
//flags 选项
//步骤1.绑定服务方式开启服务
conn=new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);
}
private class MyConn implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
//步骤3、服务返回的Binder对象传递回来
binder=(IService)service;
Log.i(TAG, "代理人返回……");
}
//只有程序异常终止才会调用
@Override
public void onServiceDisconnected(ComponentName name)
{
}
}
/**
* 解除绑定服务
* @param v
*/
public void unbind(View v)
{
unbindService(conn);
}
/**
* 此操作保证退出程序时服务解绑
*/
@Override
protected void onDestroy()
{
try
{
//服务只可以解绑一次 所以用try catch
unbind(null);
} catch (Exception e)
{
}
super.onDestroy();
}
}
ChungeService:
package com.example.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class ChungeService extends Service
{
private final String TAG="ChungeService";
@Override
public boolean onUnbind(Intent intent)
{
Log.i(TAG, "onUnbind 解除绑定……");
return super.onUnbind(intent);
}
@Override
public IBinder onBind(Intent arg0)
{
//步骤2.返回自定义的Binder对象
Log.i(TAG, "onBind 服务被成功绑定……");
return new MyBinder();
}
private class MyBinder extends Binder implements IService
{
public void callChangeName(String name)
{
changeSing(name);
}
}
@Override
public void onCreate()
{
super.onCreate();
Log.i(TAG, "onCreate 服务开始,开始唱歌……");
}
@Override
public void onDestroy()
{
super.onDestroy();
Log.i(TAG, "onDestroy 服务停止,停止唱歌……");
}
//更改歌曲名字
public void changeSing(String name)
{
Toast.makeText(getApplicationContext(), "changeSing 开始唱"+name+"……", Toast.LENGTH_SHORT).show();
}
}
IService:
package com.example.service;
public interface IService
{
public void callChangeName(String name);
}
一般通过接口暴露方法