Rom开发 音乐桌面小插件开发

一、因原生系统支持的RemoteView控件很少,特别是在动画实现的控件里面,所以需要自定义RemoteView到系统框架中,编译之后再在工程中引用。


自定义RemoteView的规范示例如下:


@RemoteView   // 此处添加RemoteView标签,表示支持RemoteView调用

publicclass WidgetProgressbar extends ProgressBar {


    /**

     * setPlayingState: TODO<br/>

     * 

     * @param pIsPlaying boolean

     * @hide   // 此处声明方法为hide类型,否则在编译整个Rom工程的时候会报错

     */

    @RemotableViewMethod  // 此处添加标签声明,表示支持RemoteView方法调用

   public void setPlayingState(boolean pIsPlaying) {

        Log.v(TAG, "------->>setPlayingState(),pIsPlaying:" + pIsPlaying);

    }



初始音乐插件播放进度条显示的实现是在MediaAppWidgetProvider中开启一个线程,通过持续刷新的方式将当前的播放进度通过RemoteView的方法将播放进度刷新到小工具上,这种方法会导致RemoteViewAction数组在刷新较长的一段时间之后溢出(因为framework的RemoteView 并没有对Action数组做清除的逻辑处理)进而导致整个音乐应用运行缓慢,最终导致ANR。所以自定义一个WidgetProgressbarextends ProgressBar)类,将进度条的刷新放在这个类中自己处理。在MediaAppWidgetProvider的更新只需要设置WidgetProgressbar中的播放状态值,及当前的播放进度。

类中还要包含对屏幕亮暗和桌面是否处于前台的广播监听处理,如果桌面处于后台或者屏幕处于暗屏状态则停止进度条的刷新,避免多余资源的耗费。

onAttachedToWindow()中注册广播监听,在onDetachedFromWindow()取消广播监听并且移除Handler中的刷新进度条的Message(避免在控件onDetachedFromWindow之后这个Handler的刷新还在循环进行,使得Handler消息队列中的消息过多导致消息队列的堵塞进而引发其他的异常,如反复切换字体大小或语言,若没有对Handler中的消息队列进行清理,会导致Launcher堆内存一直上涨。所以桌面小插件的刷新逻辑实现要特别注意Handler消息的及时清理。

我们看到很多桌面小插件都没有进度条,就是因为其刷新机制问题,所以如果不是做系统开发,只是做一般的应用开发,不要在桌面小插件上面做进度条刷新显示的实现。

而小米手机的音乐插件其实并不是一个插件,因为其实现是在Launcher上面,并不是在音乐播放器上面。因小米手机framework改造的原因得以将实现放在Launcher上面,其他平台的手机暂没注意。



2、小工具点击事件的绑定

原生音乐小工具绑定按钮点击事件是在每次更新Widget内容的时候,因为要根据当前不同的播放状态跳转到不同的页面,RemoteView的OnClickPending数组也是没有做清理的处理逻辑,这样会导致在多次绑定控件的pendingIntent之后导致音乐OOM异常。这个是安卓framework中RemoteView自身机制的缺陷。所以建议只在初始化Widget控件的时候一次性绑定所有View的PendingIntent。

 if (playerActive) {
            intent = new Intent(context, MediaPlaybackActivity.class);
            pendingIntent = PendingIntent.getActivity(context,
                    0 /* no requestCode */, intent, 0 /* no flag */);
            views.setOnClickPendingIntent(R.id.album_appwidget, pendingIntent);
        } else {
            intent = new Intent(context, MusicBrowserActivity.class);
            pendingIntent = PendingIntent.getActivity(context,
                    0 /* no requestCode */, intent,  0 /* no flag */);

    views.setOnClickPendingIntent(R.id.album_appwidget, pendingIntent);
        }



3、小工具左右切换动画实现

如果是在XML布局中直接用ViewFlipper控件则只能设置一个方向的动画,只能配置inAnimation与outAnimation,且无法通过RemoteView来重新设置参数,没有相应的接口可以调用,而通过LayoutAnimation则只能在每次移除或者加载布局的时候触发一次动画,这种实现更不靠谱。

解决方法是在framework中自定义View,再在布局中引用此自定义控件。


@RemoteView
public class WidgetViewFlipper extends ViewFlipper {


  /**
   * switchAnimation: TODO<br/>
     * 
     * @param pStrDirection String
   
   * @hide
     
 */ 

    @android.view.RemotableViewMethod
        public void setAnimationMode(String pStrDirection) {
        if (pStrDirection.equals(LEFTTORIGHT)) {
            setInAnimation(slideLeftIn());
            setOutAnimation(slideRightOut());
        } else if (pStrDirection.equals(RIGHTTOLEFT)) {
             setInAnimation(slideRightIn());
           setOutAnimation(slideLeftOut());
        }
            }

}


在调用的时候通过RemoteView调用函数设置动画方向:

        views.setString(R.id.customViewFlipper_appwidget_textShow,"setAnimationMode", WidgetViewFlipper.RIGHTTOLEFT);

其他自定义动画的实现原理同此。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值