(六)Android中Service通信

摘要:
1、 启动服务并传递参数以传递参数时,只需在startService启动的Intent中传递数据。接收参数时,可以读取onStartCommand函数中第一个参数Intent的内容,实现1.MainActivity.javapackagecom.example.shiyanshi.serviceconnected;importandroid.app.活动;重要的
一、启动Service并传递参数

传递参数时只需在startService启动的Intent中传入数据便可,接收参数时可在onStartCommand函数中通过读取第一个参数Intent的内容来实现

1.MainActivity.java

package com.example.shiyanshi.serviceconnected;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;


public class MainActivity extends Activity implements View.OnClickListener {
private EditText editText;

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

editText= (EditText) findViewById(R.id.editText);
findViewById(R.id.btnStartService).setOnClickListener(this);
findViewById(R.id.btnStopService).setOnClickListener(this);
}

@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btnStartService:

Intent intent=new Intent(MainActivity.this,MyService.class);
intent.putExtra("data",editText.getText().toString());
startService(intent);

                break;
case R.id.btnStopService:
stopService(new Intent(MainActivity.this,MyService.class));
}

}
}

2.MyService.java

package com.example.shiyanshi.serviceconnected;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {
private String data;
private boolean flag;

public MyService() {
}

@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}

@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();
flag=true;
new Thread() {
@Override
public void run() {
super.run();
while (flag) {
System.out.println(data);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

@Override
public void onDestroy() {
super.onDestroy();
flag=false;
}
}

 

3.布局文件

<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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<EditText android:text="@string/hello_world" android:layout_width="fill_parent"
android:layout_height="wrap_content"
android: />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="启动服务"
android: />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止服务"
android: />

</LinearLayout>
 二、绑定Service进行通信 

(1)Activity向Service传递消息

绑定服务后,Activity和Service之间可以通过android.os.Binder进行通信,当绑定服务时首先调用onCreate函数,然后调用Service类的onBind函数返回一个Binder,之后会调用Activity类中实现的onServiceConnected函数,该函数的第二个参数IBinder iBinder是Service类中onBind方法的返回值,通过这个Binder二者便可以成功通信。

 

 

1.MainActivity.java

package com.example.shiyanshi.serviceconnected;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;


public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection {
private EditText editText;
private MyService.Binder binder=null;

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

editText= (EditText) findViewById(R.id.editText);
findViewById(R.id.btnStartService).setOnClickListener(this);
findViewById(R.id.btnStopService).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.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btnStartService:
Intent intent=new Intent(MainActivity.this,MyService.class);
intent.putExtra("data",editText.getText().toString());
startService(intent);
break;
case R.id.btnStopService:
stopService(new Intent(MainActivity.this, MyService.class));
break;

case R.id.btnBindService:
bindService(new Intent(MainActivity.this, MyService.class), this, Context.BIND_AUTO_CREATE);
break;
case R.id.btnUnbindService:
unbindService(this);
break;
case R.id.btnSyncData:
if(binder!=null){
System.out.println("bind in not null");
binder.setData(editText.getText().toString()); //调用Bind中实现的数据交互方法
}
break;

        }

}

@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
System.out.println("*****Connected Successful*******");

binder= (MyService.Binder) iBinder;

    }

@Override
public void onServiceDisconnected(ComponentName componentName) {
System.out.println("*****Disconnected Successful*******");

}
}

2.MyService.java

package com.example.shiyanshi.serviceconnected;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class MyService extends Service {
private String data="default info";
private boolean flag;

public MyService() {
}

@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
// throw new UnsupportedOperationException("Not yet implemented");

return new Binder(); //返回值会传给onServiceConnected函数的第二个参数IBinder

    }   
    //该类是Activity和Service进行交互数据的接口

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();
System.out.println("*******onCreate********");
flag=true;
new Thread() {
@Override
public void run() {
super.run();
while (flag) {
System.out.println(data);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

@Override
public void onDestroy() {
super.onDestroy();
System.out.println("******onDestroy******");
flag=false;
}
}

(2)Service向Activity传递消息,并将传递的数据显示到Activity中

主要通过在Service中设定一个回调函数的接口,并定义一个该接口的引用,该引用的实例化是在Activity中进行的,实例化的同时会重写该接口中定义的回调函数,让该回调函数发送一个消息,并且在消息处理器(Handler)中进行更新UI线程的内容;此外在新开的Thread线程中调用该回调函数进行更新数据。

1.MainActivity.java

package com.example.shiyanshi.serviceconnected;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.util.logging.Handler;


public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection {
private EditText editText;
private MyService.Binder binder=null;
private TextView tvOut;

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

editText= (EditText) findViewById(R.id.editText);
tvOut=(TextView)findViewById(R.id.tvOut);

findViewById(R.id.btnStartService).setOnClickListener(this);
findViewById(R.id.btnStopService).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.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btnStartService:
Intent intent=new Intent(MainActivity.this,MyService.class);
intent.putExtra("data",editText.getText().toString());
startService(intent);
break;
case R.id.btnStopService:
stopService(new Intent(MainActivity.this, MyService.class));
break;
case R.id.btnBindService:
bindService(new Intent(MainActivity.this, MyService.class), this, Context.BIND_AUTO_CREATE);
break;
case R.id.btnUnbindService:
unbindService(this);
break;
case R.id.btnSyncData:
if(binder!=null){
System.out.println("bind in not null");
binder.setData(editText.getText().toString());
}
break;
}

}

@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
System.out.println("*****Connected Successful*******");
binder= (MyService.Binder) iBinder;

//设置回调函数,在回调函数中通过发送消息和消息处理器进行修改UI线程要显示的内容
binder.getService().setCallback(new MyService.Callback() {
@Override
public void onDataChange(String data) {
//tvOut.setText(data); 这里不可以直接设置,因为由新创建的线程去调用这个函数,不允许直接修改UI线程的内容
Message msg=new Message();
Bundle bundle=new Bundle();
bundle.putString("data",data);
msg.setData(bundle);
handler.sendMessage(msg); //通过handler发送消息
}
});

    }

@Override
public void onServiceDisconnected(ComponentName componentName) {
System.out.println("*****Disconnected Successful*******");

}
 

//消息处理函数,接收Message并进行处理


private android.os.Handler handler=new android.os.Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
tvOut.setText(msg.getData().getString("data"));

}
};

}
 

2.MyService.java

package com.example.shiyanshi.serviceconnected;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class MyService extends Service {
private String data="default info";
private boolean flag;

public MyService() {
}

@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
// throw new UnsupportedOperationException("Not yet implemented");
System.out.println("******onBind*****");
return new Binder(); //返回值会传给onServiceConnected函数的第二个参数IBinder
}
//该类是Activity和Service进行交互数据的接口
public class Binder extends android.os.Binder{
public void setData(String data) {
MyService.this.data=data;
}

//获取当前的MyService类的引用
public MyService getService(){
return MyService.this;
}

    }

@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();
System.out.println("*******onCreate********");
flag=true;

new Thread() {
@Override
public void run() {
super.run();
int i=0;
while (flag) {
i++;
String str=i+":"+data;
System.out.println(str);

//由新创建的线程去调用这个函数,不允许直接修改UI线程的内容
if (callback!=null){
callback.onDataChange(str);
}

                    try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

@Override
public void onDestroy() {
super.onDestroy();
System.out.println("******onDestroy******");
flag=false;
}

//创建的接口用于回调,回调函数(onDataChange)具体是在Activity中实现的



private Callback callback=null;

public void setCallback(Callback callback) {
this.callback = callback;
}

public Callback getCallback() {
return callback;
}

public static interface Callback{
void onDataChange(String data);
}









}

 

 

免责声明:文章转载自《(六)Android中Service通信》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Ubuntu 安装 Courier New字体和雅黑consolas字体产品逻辑中的—B端技术常识:同步异步接口模式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

解决ASP.NET MVC返回的JsonResult 中 日期类型数据格式问题,和返回的属性名称转为“驼峰命名法”和循环引用问题

DateTime类型数据格式问题 问题 在使用ASP.NET MVC 在写项目的时候发现,返回给前端的JSON数据,日期类型是 Date(121454578784541) 的格式,需要前端来转换一下才能用来使用。 C#对象属性名称转换成JSON自动转成“驼峰命名法” 问题 在C#中推荐的属性命名方式是“帕斯卡命名法”【首字母大写】但是在前端推荐命名方式为“...

5G名词术语

英文缩写  说明   VR(Virtual Reality) 虚拟现实   VLOG(Video blog) 视频网络日志   AR(Augmented Reality) 增强   MR(Mixed Reality) 混合现实    SON(self-organizing network)  自组织网络   CDN(c...

Android占位符

<xliff:g>标签介绍:属性id可以随便命名属性值举例说明%n$ms:代表输出的是字符串,n代表是第几个参数,设置m的值可以在输出之前放置空格%n$md:代表输出的是整数,n代表是第几个参数,设置m的值可以在输出之前放置空格,也可以设为0m,在输出之前放置m个0%n$mf:代表输出的是浮点数,n代表是第几个参数,设置m的值可以控制小数位数,...

QT5:网络

QNetworkAccessManager的post方法 多线程 同步 异步 八.QT5多线程和多进程 1.多线程 QThread是Qt线程中一个公共的抽象类,所有的线程类都是从QThread抽象类中派生的,需要实现QThread中的虚函数run(),通过调用start()函数 QThread对多线程的支持: 1.QThreadStorag...

索引节点(inode)爆满问题处理

关于磁盘空间中索引节点爆满的问题还是挺多的,借此跟大家分享几个情况: 情况一 在公司一台配置较低的Linux服务器(内存、硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h命令查看了一下磁盘使用情况,发现/data分区只使用了66%,还有12G的剩余空间,按理说不会出现这种问题。 后来用df -i查看了一下/data分区的索...

libusb函数

一、libusb常用数据结构 libusb_device *list:设备列表 libusb_device_handle *handle:设备句柄 struct libusb_device_descriptor desc:设备描述符 struct libusb_config_descriptor conf:配置描述符 二、libusb常用API函数 1...