RemoteView基础知识(一)

本文详细介绍了RemoteView在Android系统中的应用场景,包括如何在通知栏和桌面小部件中使用RemoteView进行跨进程更新视图,提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RemoteView

  • 字面意思可以翻译为远程view,该view运行于其他进程中,主要是系统进程,多用于通知栏和桌面widget中,当view运行在其他进程的时候 我们无法像在Activity中那样直接更新view,为了能够跨进程更新view,RomoteView提供了一系列的set方法

    RemoteView在通知栏中的应用简单举例

    1. 使用系统默认样式弹出一个通知栏
    Notification notification = new Notification();
    notification.icon = R.mipmap.ic_launcher;
    notification.tickerText = "hello world";
    notification.when = System.currentTimeMillis()+1000;
    notification.flags = Notification.FLAG_AUTO_CANCEL;
    Intent intent = new Intent(this,xxx.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
    notification..setLatestEventInfo(this,"","",pendingIntent);
    NotificationManager manager =(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
    manager.notify(1,notification);
    2. 自定义样式的通知栏
    
    Notification notification = new Notification();
    notification.icon = R.mipmap.ic_launcher;
    notification.tickerText = "hello world";
    notification.when = System.currentTimeMillis()+1000;
    notification.flags = Notification.FLAG_AUTO_CANCEL;
    Intent intent = new Intent(this,xxx.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
    RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.xxx);
    remoteViews.setTextViewText(R.id.xx,"xxx");
    remoteViews.setImageViewResource(R.id.xx,R.mipmap.xx);
    PendingIntent openActivityPendingIntent = PendingIntent.getActivity(this,0,new Intent(this,xxx.class),PendingIntent.FLAG_UPDATE_CURRENT);
    remoteViews.setOnClickPendingIntent(R.id.xxx,openActivityPendingIntent);
    notification.contentView = remoteViews;
    notification.contentIntent = pendingIntent;
    NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
    manager.notify(2.notification);

    RemoteViews的使用很简单,只需要提供当前应用的包名和布局文件的资源id即可创建一个RemoteViews对象,更新RemoteViews的方法比较复杂,因为RemoteViews运行在系统的进程中 我们无法直接访问里面的view 所以必须通过,RemoteViews提供的一系列方法来更新view

    remoteViews.setTextViewText(R.id.xx,"");//参数分别为TextView的id和要设置的文本
    
    remoteViews.setImageViewResource(R.id.xx,R.mipmap.xx);//参数分别为ImageView的id和要设置的图片的资源id
        remoteViews.setOnClickPendingIntent(R.id.xx,pendingIntent);//参数分别为要加点击事件的控件的id和pendingIntent
    

    RomoteViews在桌面小部件中的应用

    1. AppWidgetProvider是Android提供的用于实现桌面小部件的类,其本质是一个广播,继承自BroadcaseReceiver

      具体使用步骤可分为以下几步

      1. 定义小部件界面
        在layout中定义widget.xml文件
      2. 定义小部件配置信息
        在res/xml文件夹中定义appwidget_info.xml文件

        <?xml version="1.0" encoding="utf-8"?>
        <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:minWidth="84dp"
        android:minHeight="84dp"
        android:updatePeriodMillis="86400000"
        android:previewImage="@mipmap/ic_launcher"
        android:initialLayout="@layout/widget"
        android:resizeMode="horizontal|vertical"
        android:widgetCategory="home_screen|keyguard"
        android:initialKeyguardLayout="@layout/widget">
        <!--
        简单介绍一下上述的属性
        minWidth和minHeight是最小的宽高
        updatePeriodMillis 是指更新周期 每过一段时间appwidget会自动更新一次
        previewImage是指预览图 如果不设置则默认显示应用图标
        initialLayout是指appWidget的布局文件
        resizeMode是指appWidget的可伸缩方向
        widgetCategory是指appWidget只用的位置 包括桌面和锁屏
        initialKeyguardLayout是指appWidget在锁屏模式的资源文件
        -->
        
        </appwidget-provider>
      3. 定义小部件的实现类

        package com.zzp.example.remoteviews;
        import android.app.PendingIntent;
        import android.appwidget.AppWidgetManager;
        import android.appwidget.AppWidgetProvider;
        import android.content.Context;
        import android.content.Intent;
        import android.widget.RemoteViews;
        
        import com.zzp.example.R;
        
        /**
         *桌面小部件的实现类 具体使用方法参见本包中的ReadMe文件
         */
        public class MyAppWidgetProvider extends AppWidgetProvider{
            private static final String TAG = "MyAppWidgetProvider";
            public static final String CLICK_ACTION = "";
        
            public MyAppWidgetProvider(){
                super();
            }
        
        
            /**
             *当该窗口小部件第一次添加到桌面的时候调用该方法
             *添加多次 但只会调用一次
             *@param context
             */
            @Override
            public void onEnabled(Context context) {
                super.onEnabled(context);
            }
        
            /**
             *小部件被添加或者更新的时候回调用该方法
             *小部件的更新时机由updatePeriodMills来制定 每个周期都会自动更新一次
             *@param context
             *@param appWidgetManager
             *@param appWidgetIds
             */
            @Override
            public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
                super.onUpdate(context, appWidgetManager, appWidgetIds);
                int count = appWidgetIds.length;
                for(int i = 0;i<count;i++){
                    int appWidgetId = appWidgetIds[i];
                    //更新桌面小部件
                    onWidgetUpdate(
                    context,appWidgetManager,appWidgetId);
                }
            }
        
            /**
             *更新桌面小部件
             *@param context
             *@param appWidgetManager
             *@param appWidgetId
             */
            private void onWidgetUpdate(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
                RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget);
        
                //定义桌面小部件单击事件要发送的广播
                Intent intent = new Intent();
                intent.setAction(CLICK_ACTION);
                PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,intent,0);
                remoteViews.setOnClickPendingIntent(
                R.id.iamgeView1,pendingIntent);
                appWidgetManager.updateAppWidget(
                appWidgetId,remoteViews);
        
            }
        
            /**
             *每删除一个桌面小部件就会调用一次
             *@param context
             *@param appWidgetIds
             */
            @Override
            public void onDeleted(Context context, int[] appWidgetIds) {
                super.onDeleted(context, appWidgetIds);
            }
        
            /**
             *当最后一个桌面小部件被删除的时候会调用该方法 只会调用一次
             *@param context
             */
            @Override
            public void onDisabled(Context context) {
                super.onDisabled(context);
            }
        
            /**
             *这是广播的内置方法 用于分发具体的事件给其他方法
             *@param context
             *@param intent
             */
            @Override
            public void onReceive(Context context, Intent intent) {
                super.onReceive(context, intent);
                //这里是判断我们自己定义的action 做对应的事情 比如被单击了要做什么事情
                if(intent.getAction().equals(CLICK_ACTION)){
                    //doSomething
                }
            }
        }
        
      4. 在AndroidManifest中声明小部件

        <receiver android:name=".remoteviews.MyAppWidgetProvider">
            <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/appwidget_info" />
        
            <intent-filter>
                <action android:name="xxx" />
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <!-- 这两个action第一个是我们自定义的 第二个是作为小部件的标识而必须存在的 如果不加 那么这个receiver就不是一个桌面小部件 并且无法出现在系统的小部件列表中-->
            </intent-filter>
        </receiver>

参考资料:Android开发艺术探索

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值