Android开发-后端Model_Service
2016-01-18 16:08
417 查看
Android开发-后端Model_Service
sf2gis@163.com
2015年12月26日
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;
}
}
Intent i=newIntent(MainActivity.this,ServiceWithoutIntent.class);
i.putExtra("xx","xx123");
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
<?xmlversion="1.0" encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="lee.com.demo" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar" >
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".ServiceWithoutIntent"
android:enabled="true"
android:exported="true" >
</service>
</application>
</manifest>
//activity_main.xml
<?xmlversion="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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.support.design.widget.AppBarLayoutandroid:layout_height="wrap_content"
android:layout_width="match_parent"android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"
android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<includelayout="@layout/content_main" />
<android.support.design.widget.FloatingActionButtonandroid:id="@+id/fab"
android:layout_width="wrap_content"android:layout_height="wrap_content"
android:layout_gravity="bottom|end"android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"/>
</android.support.design.widget.CoordinatorLayout>
//content_main.xml
<?xmlversion="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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">
<TextView android:text="HelloWorld,Android!" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="NewButton"
android:id="@+id/button"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="140dp"
android:onClick="btnClick"
/>
</RelativeLayout>
//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);
}
}
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;
}
}
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
<?xmlversion="1.0" encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="lee.com.demo" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar" >
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".ServiceWithoutIntent"
android:enabled="true"
android:exported="true" >
</service>
</application>
</manifest>
//activity_main.xml
<?xmlversion="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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.support.design.widget.AppBarLayoutandroid:layout_height="wrap_content"
android:layout_width="match_parent"android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<includelayout="@layout/content_main" />
<android.support.design.widget.FloatingActionButtonandroid:id="@+id/fab"
android:layout_width="wrap_content"android:layout_height="wrap_content"
android:layout_gravity="bottom|end"android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"/>
</android.support.design.widget.CoordinatorLayout>
//content_main.xml
<?xmlversion="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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">
<TextView android:text="HelloWorld,Android!" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="NewButton"
android:id="@+id/button"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="140dp"
android:onClick="btnClick"
/>
</RelativeLayout>
//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是在主线程中工作,耗时操作会阻塞进程。
sf2gis@163.com
2015年12月26日
1 目标:后台服务功能,不具备交互展示功能。
2 原理:Activity删除交互功能。
3 流程:创建服务,创建交互内容,调用服务。
3.1 创建服务:app->java右键-》new-》service-》Service。
3.2 创建服务后会自动重写onBind()绑定响应函数,这里需要重写onCreate()服务创建响应函数和onStartCommand()服务启动响应函数。
//ServiceWithoutIntent.javapackage 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;
}
}
3.3 创建交互内容:intent
在页面中添加一个Button,设置响应函数为btnClick(),在其中设置intent和启动服务。Intent i=newIntent(MainActivity.this,ServiceWithoutIntent.class);
i.putExtra("xx","xx123");
3.4 调用服务:startService()
startService(i);3.5 示例
//结果:点击按钮后在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
<?xmlversion="1.0" encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="lee.com.demo" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar" >
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".ServiceWithoutIntent"
android:enabled="true"
android:exported="true" >
</service>
</application>
</manifest>
//activity_main.xml
<?xmlversion="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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.support.design.widget.AppBarLayoutandroid:layout_height="wrap_content"
android:layout_width="match_parent"android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"
android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<includelayout="@layout/content_main" />
<android.support.design.widget.FloatingActionButtonandroid:id="@+id/fab"
android:layout_width="wrap_content"android:layout_height="wrap_content"
android:layout_gravity="bottom|end"android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"/>
</android.support.design.widget.CoordinatorLayout>
//content_main.xml
<?xmlversion="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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">
<TextView android:text="HelloWorld,Android!" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="NewButton"
android:id="@+id/button"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="140dp"
android:onClick="btnClick"
/>
</RelativeLayout>
//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);
}
}
4 方法:前后台通信Intent,Binder,Connection
服务在启动时会调用onCreate()响应函数。服务关闭时会调用onDestroy()响应函数。4.1 开启服务:使用startService()/stopService()单纯的调用服务,并传递Intent作为单次通信数据。
服务可以监听onStartCommand()监听startStartService()。4.2 绑定服务:使用bindService()/unbindService()调用服务,建立调用方和服务之间连接ServiceConnection,使用Binder进行实时通信。
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;
}
}
4.3 区别:startService(),只进行服务调用,无其它作用。bindService()调用服务的同时建立1:1关系,如果主动调用unbindService()将会同时关闭调用方和服务。
4.4 示例
//结果:点击按钮后在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
<?xmlversion="1.0" encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="lee.com.demo" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar" >
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".ServiceWithoutIntent"
android:enabled="true"
android:exported="true" >
</service>
</application>
</manifest>
//activity_main.xml
<?xmlversion="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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.support.design.widget.AppBarLayoutandroid:layout_height="wrap_content"
android:layout_width="match_parent"android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<includelayout="@layout/content_main" />
<android.support.design.widget.FloatingActionButtonandroid:id="@+id/fab"
android:layout_width="wrap_content"android:layout_height="wrap_content"
android:layout_gravity="bottom|end"android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"/>
</android.support.design.widget.CoordinatorLayout>
//content_main.xml
<?xmlversion="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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">
<TextView android:text="HelloWorld,Android!" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="NewButton"
android:id="@+id/button"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="140dp"
android:onClick="btnClick"
/>
</RelativeLayout>
//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);
}
}
}
4.5 多线程服务IntentService
Service的增强版本,开启单独的线程工作。Service是在主线程中工作,耗时操作会阻塞进程。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析