Android 服务通信方案总结

关于Android中的服务:


启动服务和绑定服务两种,常用于耗时操作。



//1、启动服务
Intent intent = new Intent(StartActivity.this, ServiceSimpleCase.class);
startService(intent);//配合stopService()使用。

//2、绑定服务,结合Parcel,transcat()
bindService(intent, serviceConnection, BIND_AUTO_CREATE);


绑定服务,activity和service数据通信
1、Parcel 处理


    /**
* 服务使用ServiceConnection。
*/
ServiceConnection serviceConnection = new ServiceConnection() {
//绑定失败
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Log.v("System.out.print.sax", "服务绑定失败。");
}
//绑定成功,进行数据处理。
@Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
// TODO Auto-generated method stub
BinderSimpleCase binder = (BinderSimpleCase) iBinder;
String testData = binder.getTestData();
Log.v("System.out.print.kuatang", "【BinderSimpleCase】自定义服务内部Binder类测试方法数据值: " + testData);

Parcel data = Parcel.obtain();
data.writeString("test data");
data.writeDouble(11.20d);
data.writeInt(99);
Parcel reply = Parcel.obtain();
try {
binder.transact(0, data, reply, 1);// 四个参数是对应的。
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.v("System.out.print.sax", "onServiceConnected-->" + e.getMessage());
}
}
};

具体的服务:
package com.kuatang.service;


import android.app.Service;


import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
/**
 * Service:
 * 1、需要有一个public方法,可适用于【启动服务】,也可用于【绑定服务】。
 * 2、onBinder(Intent)方法的重写。
 * 3、onTransact()结合transact(),两个方法后者在UI中服务被绑定成功后使用,
 * 几乎是同步的两个方法,共有四个参数,Parcel(轻量级序列化类)类似于web开发的请求和响应。
 * 4、内部类继承Binder。
 * 5、使用服务一定要注册声明。
 * @author TANG_YUEDI
 *
 */
public class ServiceSimpleCase extends Service{

private static final String TAG = "System.out.print.sax";


/**
* 此方法用于UI绑定service,是必须重写的方法,根据官方文档,需返回一个Binder对象。
*/
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub

IBinder iBinder = new BinderSimpleCase();
return iBinder;//这个对象就是在UI部分服务启动成功的方法中可获取,并调用方法。
}


/**
* 在该服务首次创建时调用。
*/
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.v(TAG, "ServiceSimpleCase is creating");
}


@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.v(TAG, "ServiceSimpleCase is destoryed");
super.onDestroy();
}


/**
* Intent:intent;flags:标识,与前文对照;startId:服务执行的次数。
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.v(TAG, "ServiceSimpleCase onStartCommand-->" + intent
+ flags + startId);
return super.onStartCommand(intent, flags, startId);
}

public class BinderSimpleCase extends Binder{


/**
* code:编号。
* data:传来的数据。
* reply:传来时为空值,本方法调用完成以后,处理后的值可返回到UI。
* flags:标识。
*/
@Override
protected boolean onTransact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
// TODO Auto-generated method stub

//获取Parcel数据时先把指针挪移到最前面。
data.setDataPosition(0);
String parcelStr = data.readString();
Double parcelDouble = data.readDouble();
int parcelInt = data.readInt();
Log.v(TAG, "Parcel测试数据输出结果:整型值=" + parcelInt
+ "字符串值=" + parcelStr + "双精度值=" + parcelDouble);
return super.onTransact(code, data, reply, flags);
}

public String getTestData(){
return "get a data for ServiceSimpleCase";
}

}


}
__________________________________________________________________________________


2、使用回调进行数据通信。
   具体例子……
   
3、广播


——————————————————————————————————————————————————————————————————————————————————
关于AppWidget




import com.example.kuatang.ui.StartActivity;


import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.RemoteViews;


/**
 * AppWidget:例如桌面的时钟,播放中的音乐应用可以在桌面进行更新状态。
 * 创建AppWidget需要的几个步骤:
 * 1、AppWidgetProviderInfo对象,为其提供元数据,布局等内容,
 * 被定义在XML布局文件当中。此处为"XML"文件夹下的example_appwidget_provider.xml。
 * 2、需要一个类继承AppWidgetProvider类,实现其中生命周期等方法。
 * 3、需要一个布局用以展示其样式图标(appwidget_layout.xml)。
 * 4、需要对其进行注册。
 * @author TANG_YUEDI
 *
 */
public class ExampleAppWidgetProvider extends AppWidgetProvider{

private static final String TAG = "System.out.print.kuatang";
/**
* 自定义的广播机制使用action,注意如果需要使用该中方式,务必在配置文件中进行注册声明。
*/
private static final String APP_WIDGET_ACTION = "kuatang.appwidget.action.update";


@Override
public void onAppWidgetOptionsChanged(Context context,
AppWidgetManager appWidgetManager, int appWidgetId,
Bundle newOptions) {
// TODO Auto-generated method stub
Log.v(TAG, appWidgetManager + " appWidgetId=" + appWidgetId + "newOptions=" + newOptions);
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId,
newOptions);
}


@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
Log.v(TAG, "appWidgetIds" + appWidgetIds);
super.onDeleted(context, appWidgetIds);
}


@Override
public void onDisabled(Context context) {
// TODO Auto-generated method stub
super.onDisabled(context);
}


@Override
public void onEnabled(Context context) {
// TODO Auto-generated method stub
super.onEnabled(context);
}
   /**
    * 实际上是以广播的方式进行。
    */
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if (action.equals(APP_WIDGET_ACTION)){
/* //更新状态业务处理
// RemoteViews:代表AppWidgetProvider里面的所有View。
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), 
R.layout.appwidget_layout);
// 假设现在的控件中含有一个默认的图片,当触发到该action的时候,进项图片的更换功能。
// 参数解释:第一个参数表示控件布局里的图片ID,第二个表示要更换成什么样的图片。
remoteViews.setImageViewResource(R.id.update_image, R.drawable.src_image);
// 需要有AppWidgetManager类。
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
// 下面的对象所代表的为整个AppWidgetProvider类。
ComponentName componentName = new ComponentName(context, ExampleAppWidgetProvider.class);
appWidgetManager.updateAppWidget(componentName, remoteViews);
*/
} else {
// 此处需要一个else,原因为如果action与自定义的不相同时,根据AppWidget的生命周期,
// 其余四个方法分别对应于Android内置的四个action,同样会调用this方式。
super.onReceive(context, intent);
}

}


@Override
public void onRestored(Context context, int[] oldWidgetIds,
int[] newWidgetIds) {
// TODO Auto-generated method stub
super.onRestored(context, oldWidgetIds, newWidgetIds);
}
    /**
     * 以getActivity方法为例说明。
     * 
     * 创建PendingIntent对象(类似于回调函数。相当于一种挂起闲置的状态,只有在触发到该预定好的事件时,方会调用;将其比喻为一个包,而包中物品或者处理为Intent)。
     * 以其静态方法创建:
     * 1、getActivity(Context context, int requestCode, Intent intent, int flags);
     * 2、getBroadcast(Context context, int requestCode, Intent intent, int flags);
     * 3、getService(Context context, int requestCode, Intent intent, int flags);
     * 
     * 创建RemoteViews对象,该对象表示了一系列的view对象,更加重要的是该对象与应用程序运行在不同的进程里。
     * AppWidget是运行于Home Screen里面。
     * 监听事件:
     * remoteviews.setOnClickPendingIntent(R.id..., PendingIntent)。
     */
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
for (int i = 0; i < appWidgetIds.length; i++){
Log.v(TAG, "appWidgetIds[i]=" + appWidgetIds[i]);
Intent intent = new Intent(context, StartActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 1);
//          使用广播方式更新AppWidget的状态。
// Intent intent2 = new Intent();
// intent2.setAction(APP_WIDGET_ACTION);
// PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, intent2, 0);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), 
R.layout.appwidget_layout);
// 参数一指的是布局样式中所使用的空间的id
remoteViews.setOnClickPendingIntent(R.id.appwidget_ic_launcher, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}


}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值