Android笔记之Service
Service可以在后台保持运行状态,这是Activity办不到的,在特定条件下,Activity会被系统回收。比如监听服务器之类的长期操作,只能用Service来执行。
一.如何声明启动Service
1.创建类扩展自Service,在AndroidManifest.xml中注册Service.
2.创建一个Intent来启动Service。调用startService(intent)。补充:可以在Service中重写public int onStartCommand(Intent intent, int flags, int startId)方法来设置Service启动进行的操作。
例如:启动后让其输出”服务正在运行“
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
new Thread()
{
@Override
public void run()
{
while(true)
{
super.run();
System.out.println("服务正在运行");
try
{
sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
return super.onStartCommand(intent, flags, startId);
}
3.在Service中重写onCreate()和onDestroy()方法。
二.如何绑定服务
启动服务也可以用绑定服务的方式。通过
public abstract boolean bindService (Intent service, ServiceConnection conn, int flags) 可以绑定服务,其中conn为要与服务绑定的活动, BIND_AUTO_CREATE表示当服务一建立就自动绑定。重写public void onServiceConnected(ComponentName name, IBinder service)和public void onServiceDisconnected(ComponentName name)来执行服务绑定和解除绑定时执行的操作。
出现的错误:
Intent调用new Intent()要在onCreate方法里面来执行,否则运行时会发生错误java.lang.RuntimeException: Unable to instantiate activity ComponentInfo
在MainActivity中:
public class MainActivity extends Activity implements OnClickListener, ServiceConnection
{
Intent intent = null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(MainActivity.this,MyService.class);
findViewById(R.id.btnStartService).setOnClickListener(this);
findViewById(R.id.btnStopService).setOnClickListener(this);
findViewById(R.id.btnStartService).setOnClickListener(this);
findViewById(R.id.btnBindService).setOnClickListener(this);
findViewById(R.id.btnUnbindService).setOnClickListener(this);
}
@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;
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.btnStartService:
startService(intent);
break;
case R.id.btnStopService:
stopService(intent);
break;
case R.id.btnBindService:
bindService(intent,this,Context.BIND_AUTO_CREATE);
break;
case R.id.btnUnbindService:
unbindService(this);
break;
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
System.out.println("Service connected");
}
@Override
public void onServiceDisconnected(ComponentName name)
{
}
}
在MyService中
public class MyService extends Service
{
@Override
public IBinder onBind(Intent intent)
{
return new Binder();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
new Thread()
{
@Override
public void run()
{
while(true)
{
super.run();
System.out.println("服务正在运行");
try
{
sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
return super.onStartCommand(intent, flags, startId);
}
}
三.Service的生命周期
有两个方法
pubic void onCreate()
public void onDestroy();
1.同时启动和绑定服务,则需要停止服务和解除绑定,服务才停止
2.当服务与某个activity绑定的时候,当acitivity消除的时候,Service会自动解除绑定。
3.重复启动服务时,onCreate之后执行一次,而onStartCommand每次启动都会执行。
四.启动Service并传递数据
只需要在上面的基础之上通过Intent传递参数,也可以通过绑定服务来传递参数。
MainActivity中
public class MainActivity extends Activity implements OnClickListener, ServiceConnection
{
private EditText etData;
Intent intent = null;
private MyService.Binder binder = null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(MainActivity.this,MyService.class);
etData = (EditText) findViewById(R.id.editText1);
findViewById(R.id.btnStartService).setOnClickListener(this);
findViewById(R.id.btnStopService).setOnClickListener(this);
findViewById(R.id.btnStartService).setOnClickListener(this);
findViewById(R.id.btnBindService).setOnClickListener(this);
findViewById(R.id.btnUnbindService).setOnClickListener(this);
findViewById(R.id.btnSyncData).setOnClickListener(this);
}
@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;
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.btnStartService:
intent.putExtra("data", etData.getText().toString());
startService(intent);
break;
case R.id.btnStopService:
stopService(intent);
break;
case R.id.btnBindService:
bindService(intent,this,Context.BIND_AUTO_CREATE);
break;
case R.id.btnUnbindService:
unbindService(this);
break;
case R.id.btnSyncData:
if (binder != null)
{
binder.setData(etData.getText().toString());
}
break;
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
binder = (Binder) service;
}
@Override
public void onServiceDisconnected(ComponentName name)
{
}
}
MyService中
public class MyService extends Service
{
private String data = "这是默认信息";
private boolean running = false;
@Override
public IBinder onBind(Intent intent)
{
return new Binder();
}
public class Binder extends android.os.Binder
{
public void setData(String data)
{
MyService.this.data = data;
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
data = intent.getStringExtra("data");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onCreate()
{
super.onCreate();
running = true;
new Thread()
{
public void run()
{
super.run();
while (running)
{
System.out.println(data);
try
{
sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
@Override
public void onDestroy()
{
super.onDestroy();
running = false;
}
}