志达IT
做快乐程序员

android service(android桌面小组件开发)

androidservice

Service意为:服务,是一种运转时用户不可见的活动机制。典型的场景:音乐后台播放。
留意:Service不同与子线程,Service是运转在主线程中的,因而不能进行耗时操作。
2.Service的创立
要想完成一个Service,咱们需求承继体系的Service类新建一个自己的Service类,比方叫MyService,代码如下:
importandroid.app.Service;
importandroid.content.Intent;
importandroid.os.IBinder;
importandroid.util.Log;
importandroidx.annotation.Nullable;
publicclassMyServiceextendsService{
privatestaticfinalStringTAG=”tag”;
@Override
publicvoidonCreate(){
super.onCreate();
Log.d(TAG,”onCreate:”);service
}
@Override
publicintonStartCommand(Intentintent,intflags,intstartId){
Log.d(TAG,”onStartCommand:”);
returnsuper.onStartCommand(intent,flags,startId);
}
@Nullable
@Override
publicIBinderonBind(Intentintent){
Log.d(TAG,”onBind:”);
returnnull;
}
@Override
publicbooleanonUnbind(Intentintent){
Log.d(TAG,”onUnbind:”);
returnsuper.onUnbind(intent);
}
@Override
publicvoidonDestroy(){
super.onDestroy();
Log.d(TAG,”onDestroy:”);
}
}
一般需求重写其中的几个重要方法:onCreate、onBind、onStartCommand。
留意:Service作为四大组件之一,跟Activity相同要在Manifest文件中注册这个Service
2.Service的发动
Service有两种发动方法,绑定式(bindService)和非绑定式(startService)。
与Activity相同,经过Intent发动。
2.1startService方法
有了MyService类之后,接下来就能够发动这个Service了。发动方法跟咱们翻开一个Activity很类似,也用到了Intent。
一般,咱们是在Activity或许Fragment中发动一个Service,去组织这个Service在后台做一些用户看不见的事情。
代码示例:
Intentintent=newIntent(this,MyService.class);
startService(intent);
特色:
一旦服务开启就跟发动者没关系了,会无限期运转,即使发动者退出,service依然在后台运转。
发动者不能调用service里边的方法。
2.2bindService方法
除了直接发动一个Service,还能够经过绑定的方法开启一个Service。
这种方法稍微杂乱一些,因为这时的Service是与调用者本身(Activity或Fragment)绑定在一起的,涉及到信息交互。
代码示例:
Intentintent=newIntent(this,MyService.class);
bindService(intent,conn,BIND_AUTO_CREATE);
特色:
绑定服务后,服务就跟调用者的生命周期绑定在一起了,假如调用者毁掉,服务也会跟着被毁掉。
调用者能够调用service里边的方法。
3.配套视频讲解
配套视频-Android中的Service介绍

android桌面小组件开发

做桌面组件已经是两年多前的工作,今日略微做个记录。
需求
三种大小的组件:2*2,4*2,4*4
能够改写数据
点击跳到App内落地页
完成
1.声明Widget的特点
在res/xml目录下创立xml文件,里边包括宽高、改写时刻等特点,所以这儿界说3种xml
2*2
<appwidget-providerxmlns:android=”http://schemas.android.com/apk/res/android”android:initialLayout=”@layout/desk_widget_2_2″android:minHeight=”110dp”android:minWidth=”155dp”android:previewImage=”@drawable/desk_widget_icon_2_2″android:updatePeriodMillis=”72720000″android:resizeMode=”none”android:widgetCategory=”home_screen”>appwidget-provider>
4*2
<appwidget-providerxmlns:android=”http://schemas.android.com/apk/res/android”android:initialLayout=”@layout/desk_widget_4_2″android:minHeight=”110dp”android:minWidth=”375dp”android:previewImage=”@drawable/desk_widget_icon_4_2″android:updatePeriodMillis=”72720000″android:resizeMode=”none”android:widgetCategory=”home_screen”>appwidget-provider>
4*4
<appwidget-providerxmlns:android=”http://schemas.android.com/apk/res/android”android:initialLayout=”@layout/desk_widget_4_4″android:minHeight=”280dp”android:minWidth=”375dp”android:previewImage=”@drawable/desk_widget_icon_4_4″android:updatePeriodMillis=”72720000″android:resizeMode=”none”android:widgetCategory=”home_screen”>appwidget-provider>
三种xml界说根本一样,对各个特点进行一下说明:
android:minWidth:最小宽度
android:minHeight:最小高度
android:updatePeriodMillis:更新widget的时刻间隔(ms)
android:previewImage:预览图片,拖动小部件到桌面时有个预览图
android:initialLayout:加载到桌面时对应的布局文件
android:resizeMode:拉伸的方向
android:widgetCategory:是否能够显现在主屏幕(home_screen)或确定屏幕(keyguard)上,5.0及以上只要home_screen有用
在设置宽高时遇到一些问题,宽高其实会直接决定卡片在手机屏幕上占的格子格子数*70-30=长度。所以2*2的卡片理论上宽高都是110dp,实际运用时发现如果手机一行有4个icon那么显现是正常的,如果手机一行有5个icon,那个两个格子的宽度是小于咱们需求的宽度的。
在实际运用中都是设置的实际宽高,这样或许组件在某些手机上占用了过大的距离,但是能保证显现完好。service
2.创立布局文件

3.办理Widget状况
系统提供了AppWidgetProvider这个类,咱们来看看它的源码:
publicvoidonReceive(Contextcontext,Intentintent){//Protectagainstrogueupdatebroadcasts(notreallyasecurityissue,//justfilterbadbroacastsoutsosubclassesarelesslikelytocrash).Stringaction=intent.getAction();if(AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)){Bundleextras=intent.getExtras();if(extras!=null){int[]appWidgetIds=extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);if(appWidgetIds!=null&&appWidgetIds.length>0){this.onUpdate(context,AppWidgetManager.getInstance(context),appWidgetIds);}}}elseif(AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)){Bundleextras=intent.getExtras();if(extras!=null&&extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)){finalintappWidgetId=extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);this.onDeleted(context,newint[]{appWidgetId});}}elseif(AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)){Bundleextras=intent.getExtras();if(extras!=null&&extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)&&extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS)){intappWidgetId=extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);BundlewidgetExtras=extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);this.onAppWidgetOptionsChanged(context,AppWidgetManager.getInstance(context),appWidgetId,widgetExtras);}}elseif(AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)){this.onEnabled(context);}elseif(AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)){this.onDisabled(context);}elseif(AppWidgetManager.ACTION_APPWIDGET_RESTORED.equals(action)){Bundleextras=intent.getExtras();if(extras!=null){int[]oldIds=extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);int[]newIds=extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);if(oldIds!=null&&oldIds.length>0){this.onRestored(context,oldIds,newIds);this.onUpdate(context,AppWidgetManager.getInstance(context),newIds);}}}}
这儿边就包括了Widget的几个生命周期:onEnabled、onAppWidgetOptionsChanged、onDeleted、onDisabled、onRestored、onUpdate,可见生命周期的控制是onReceive函数中完成的。
下面能够看一下咱们运用AppWidgetProvider做的一些工作
3.1界说一个基类BaseWidgetProvider
声明Action
publicstaticfinalStringAPP_STATE_BACK=”android.appwidget.action.APP_STATE_BACK”;
持有AppWidgetManager,需求留意的是AppWidgetManager是一个单例
AppWidgetManager.getInstance(context);
持有所有组件的id,能够通过AppWidgetManager去获取。这儿也有一个需求留意的点,就是同一种组件是能够被重复增加的,所以一个provider会对应多个组件。
int[]ids=appWidgetManager.getAppWidgetIds(newComponentName(context,this.getClass()));
onReceive中要做的工作
action状况对应的行为
网络状况变化(可用)/App切到后台/用户登录:改写组件
用户退出登录:重置组件
其他:交给完成类处理
更新Widget
将子类加载好的remoteViews设置给对应的组件
mAppWidgetmanager.updateAppWidget(appWidgetId,remoteViews);
3.2完成类逻辑
BaseWidgetProvider分发的action
根本是点击跳转行为,跳转的url从onReceive中的intent中获取,intent中的url是怎么塞进去后面会说到
初始化Widget
创立RemoteViews,并且给View设值,方法比较特别
RemoteViewsremoteViews=newRemoteViews(context.getPackageName(),getViewLayout());
remoteViews.setViewVisibility(@IdResintviewId,@View.Visibilityintvisibility)
remoteViews.setTextViewText
remoteViews.setImageViewBitmap
增加点击事件
这个进程需求运用RemoteViews和PackageManager
增加翻开App的行为
PackageManagerpackageManager=context.getPackageManager();intent=packageManager.getLaunchIntentForPackage(context.getPackageName());intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);PendingIntentpendingIntent=PendingIntent.getActivity(context,0,intent,PendingIntent.FLAG_IMMUTABLE);remoteViews.setOnClickPendingIntent(id,pendingIntent);
增加跳转到指定页面的行为
Intentintent=newIntent(action);intent.setData(Uri.parse(url));intent.setClass(context,cls);PendingIntentpendingIntent=PendingIntent.getBroadcast(context,0,intent,PendingIntent.FLAG_IMMUTABLE|PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(viewId,pendingIntent);
5.AndroidManifest注册桌面组件
咱们界说了3种组件,这儿对应也是注册3个receiver。至于为什么是receiver,由于AppWidgetProvider的父类是BroadcastReceiver。
<receiverandroid:name=”.desk.DeskWidgetMinProvider”android:exported=”true”><intent-filter><actionandroid:name=”android.appwidget.action.APPWIDGET_UPDATE”/><actionandroid:name=”android.appwidget.action.APP_STATE_BACK”/><actionandroid:name=”android.appwidget.action.NET_CONNECT_AVAILABLE”/><actionandroid:name=”android.appwidget.action.USER_STATE_ENTER”/><actionandroid:name=”android.appwidget.action.USER_STATE_EXIT”/>intent-filter><meta-dataandroid:name=”android.appwidget.provider”android:resource=”@xml/desk_widget_2_2″/>receiver><receiverandroid:name=”.desk.DeskWidgetMediumProvider”android:exported=”true”><intent-filter><actionandroid:name=”android.appwidget.action.APPWIDGET_UPDATE”/><actionandroid:name=”android.appwidget.action.APP_STATE_BACK”/><actionandroid:name=”android.appwidget.action.NET_CONNECT_AVAILABLE”/><actionandroid:name=”android.appwidget.action.USER_STATE_ENTER”/><actionandroid:name=”android.appwidget.action.USER_STATE_EXIT”/>intent-filter><meta-dataandroid:name=”android.appwidget.provider”android:resource=”@xml/desk_widget_4_2″/>receiver><receiverandroid:name=”.desk.DeskWidgetMaxProvider”android:exported=”true”><intent-filter><actionandroid:name=”android.appwidget.action.APPWIDGET_UPDATE”/><actionandroid:name=”android.appwidget.action.APP_STATE_BACK”/><actionandroid:name=”android.appwidget.action.NET_CONNECT_AVAILABLE”/><actionandroid:name=”android.appwidget.action.USER_STATE_ENTER”/><actionandroid:name=”android.appwidget.action.USER_STATE_EXIT”/>intent-filter><meta-dataandroid:name=”android.appwidget.provider”android:resource=”@xml/desk_widget_4_4″/>receiver>

赞(0)
未经允许不得转载:志达IT网站 » android service(android桌面小组件开发)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

志达IT网站 每天分享编程和互联网的IT技术博客

登录/注册联系我们