Android 服务通信方案总结

    xiaoxiao2025-10-17  11

    关于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); } }
    转载请注明原文地址: https://ju.6miu.com/read-1303244.html
    最新回复(0)