Android开发-后端Model_Service
2015年12月26日
//ServiceWithoutIntent.java
package lee.com.demo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class ServiceWithoutIntent extends Service {
public ServiceWithoutIntent() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d("ServiceWithoutIntent", "created.");
}
@Override
public int onStartCommand(Intent intent, int flags, intstartId) {
Log.d("ServiceWithoutIntent", "onStartCommand.");
String info="intent="+intent.getStringExtra("xx")+",flag="+flags+",startId="+startId;
Log.d("ServiceWithoutIntent",info);
returnsuper.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communicationchannel to the service.
Log.d("ServiceWithoutIntent","Binded..");
return null;
}
}
在页面中添加一个Button,设置响应函数为btnClick(),在其中设置intent和启动服务。
Intent i=newIntent(MainActivity.this,ServiceWithoutIntent.class);
i.putExtra("xx","xx123");
startService(i);
//结果:点击按钮后在logcat中出现以下信息
01-16 17:59:29.32520378-20378/lee.com.demo D/ServiceWithoutIntent: onStartCommand.
01-16 17:59:29.32520378-20378/lee.com.demo D/ServiceWithoutIntent: intent=xx123,flag=0,startId=1
//ServiceWithoutIntent.java
package lee.com.demo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class ServiceWithoutIntent extends Service {
public ServiceWithoutIntent() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d("ServiceWithoutIntent", "created.");
}
@Override
public int onStartCommand(Intent intent, int flags, intstartId) {
Log.d("ServiceWithoutIntent", "onStartCommand.");
String info="intent="+intent.getStringExtra("xx")+",flag="+flags+",startId="+startId;
Log.d("ServiceWithoutIntent",info);
returnsuper.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communicationchannel to the service.
Log.d("ServiceWithoutIntent","Binded..");
return null;
}
}
//AndroidManifest.xml
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar" >
android:enabled="true"
android:exported="true" >
//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:fitsSystemWindows="true"
tools:context=".MainActivity"
android:id="@+id/main">
android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay" />
android:layout_gravity="bottom|end"android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"/>
//content_main.xml
xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"
android:layout_height="match_parent"android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main" tools:context=".MainActivity"
android:id="@+id/ContentMainLayout">
android:id="@+id/textView" />
//MainActivity.java
package lee.com.demo;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab =(FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(newView.OnClickListener() {
@Override
public void onClick(Viewview) {
Snackbar.make(view,"Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
@Override
public booleanonCreateOptionsMenu(Menu menu) {
// Inflate the menu; this addsitems to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItemitem) {
// Handle action bar item clickshere. The action bar will
// automatically handle clicks onthe Home/Up button, so long
// as you specify a parentactivity in AndroidManifest.xml.
int id = item.getItemId();
//noinspectionSimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
returnsuper.onOptionsItemSelected(item);
}
public void btnClick(View v){
Log.d("MainActivity", "xxButton click");
Intent i=newIntent(MainActivity.this,ServiceWithoutIntent.class);
i.putExtra("xx","xx123");
startService(i);
}
}
服务在启动时会调用onCreate()响应函数。服务关闭时会调用onDestroy()响应函数。
服务可以监听onStartCommand()监听startStartService()。
ServiceConnection可以监听服务的连接、断开状态。
ServiceConnection conn = newServiceConnection() {
@Override
public voidonServiceConnected(ComponentName name, IBinder service) {
Log.d("conn","onServiceConnected="+name+","+service.toString());
ServiceWithoutIntent.MyBindermyBinder = (ServiceWithoutIntent.MyBinder)service;
Log.d("conn","count=" + myBinder.getCount());
if(null==binder) {
binder=myBinder;
}
}
@Override
public voidonServiceDisconnected(ComponentName name) {
Log.d("conn","onServiceDisconnected="+name);
}
};
Binder将进行实时通信,需要自定义通信方法。
Log.d("conn", "count=" +binder.getCount());
binder.setCount(binder.getCount()+1);
服务可以监听onBind()监听bindService(),连接可以监听onServiceConnected()监听连接建立,onServiceDisonnected()监听连接的意外断开。
在onBind()中要返回一个IBinder对象,一般使用内部类扩展Binder类,定义通信协议。
public class MyBinder extends Binder {
private int count=5;
public int getCount(){
return count;
}
public void setCount(int count){
this.count=count;
}
}
//结果:点击按钮后在logcat中出现以下信息
01-16 22:56:42.62325556-25556/lee.com.demo D/MainActivity: xx Button click
01-16 22:56:42.62925556-25556/lee.com.demo D/ServiceWithoutIntent: created.
01-16 22:56:42.62925556-25556/lee.com.demo D/ServiceWithoutInten2: Binded.
01-16 22:56:42.62925556-25556/lee.com.demo D/ServiceWithoutIntent2: intent=xx123
01-16 22:56:42.63225556-25556/lee.com.demo D/conn:onServiceConnected=ComponentInfo{lee.com.demo/lee.com.demo.ServiceWithoutIntent},lee.com.demo.ServiceWithoutIntent$MyBinder@59670e1
01-16 22:56:42.63225556-25556/lee.com.demo D/conn: count=5
//ServiceWithoutIntent.java
package lee.com.demo;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class ServiceWithoutIntent extends Service {
public ServiceWithoutIntent() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d("ServiceWithoutIntent", "created.");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("ServiceWithoutIntent","Destory");
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communicationchannel to the service.
Log.d("ServiceWithoutInten2","Binded.");
Log.d("ServiceWithoutIntent2","intent="+intent.getStringExtra("xx"));
return new MyBinder();
}
public class MyBinder extends Binder {
private int count=5;
public int getCount(){
return count;
}
public void setCount(int count){
this.count=count;
}
}
}
//AndroidManifest.xml
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar" >
android:enabled="true"
android:exported="true" >
//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:fitsSystemWindows="true"
tools:context=".MainActivity"
android:id="@+id/main">
android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay" />
android:layout_gravity="bottom|end"android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"/>
//content_main.xml
xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"
android:layout_height="match_parent"android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main"tools:context=".MainActivity"
android:id="@+id/ContentMainLayout">
android:id="@+id/textView" />
//MainActivity.java
package lee.com.demo;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab =(FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(newView.OnClickListener() {
@Override
public void onClick(Viewview) {
Snackbar.make(view,"Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action",null).show();
}
});
}
@Override
public booleanonCreateOptionsMenu(Menu menu) {
// Inflate the menu; this addsitems to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public booleanonOptionsItemSelected(MenuItem item) {
// Handle action bar item clickshere. The action bar will
// automatically handle clicks onthe Home/Up button, so long
// as you specify a parentactivity in AndroidManifest.xml.
int id = item.getItemId();
//noinspectionSimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private ServiceWithoutIntent.MyBinder binder = null;
public void btnClick(View v){
Log.d("MainActivity","xx Button click");
Intent i=newIntent(MainActivity.this,ServiceWithoutIntent.class);
i.putExtra("xx","xx123");
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name,IBinder service) {
Log.d("conn","onServiceConnected="+name+","+service.toString());
ServiceWithoutIntent.MyBinder myBinder =(ServiceWithoutIntent.MyBinder)service;
Log.d("conn","count=" + myBinder.getCount());
if(null==binder) {
binder=myBinder;
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("conn","onServiceDisconnected="+name);
}
};
if(null==binder) {
bindService(i, conn, BIND_AUTO_CREATE);
}
// else if(7==binder.getCount()){
// unbindService(conn);
// }
else{
Log.d("conn", "count=" +binder.getCount());
binder.setCount(binder.getCount()+1);
}
}
}
Service的增强版本,开启单独的线程工作。
Service是在主线程中工作,耗时操作会阻塞进程。