android默认壁纸的历史,Android 默认壁纸 简单分析

Android的背景墙纸功能的实现主要由散布在下面几个文件中的类来完成:

(1)frameworks/base/core/java/android/app/WallpaperManager.java

提供了API类,类WallpaperManager的各种函数接口为应用开发者所使用。

(2)frameworks/base/services/java/com/android/server/WallpaperManagerService.java

上述的API类将跨进程调用到system_server进程中的服务类WallpaperManagerService

(3)frameworks/base/core/java/android/service/wallpaper/WallpaperService.java

定义了抽象类WallpaperServic以及内嵌的墙纸绘制引擎基类Engine(子类用于实现墙纸的绘制渲染,若需preview则需创建多个引擎子类实例)。另外,该文件所在文件夹中还定义了几个AIDL接口文件,用于跨进程的调用。

(4)frameworks/base/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java

类ImageWallpaper实现了上面的WallpaperServic,同时其里面嵌套类DrawableEngine作为一个引擎子类,用于HomeScreen状态下的墙纸的渲染绘制(见其drawFrameLocked函数以及drawWallpaperWithCanvas和drawWallpaperWithOpenGL,后者用于当机器的内存有512MB时采用硬件加速的OpenGL进行绘制渲染,因为其更耗内存)。在drawFrameLocked中 ,是否真的要绘制更新,则由是否可见(变量mVisible)、是否需要绘制更新(mRedrawNeeded)和位置偏移有改变(mOffsetsChanged)来控制。

背景图片的绘制区域,则在updateWallpaperLocked中通过WallpaperManager获取背景图的位图来得到:

mBackground = mWallpaperManager.getBitmap();

注意:所得到的位图的尺寸则在WallpaperManagerService.java中确定,见WallpaperManagerService的两个函数getWidthHint和getHeightHint。而后两者中的背景图片中的高和寬的值则由WallpaperManagerService.loadSettingsLocked装载手机中的/data/system/wallpaer_info.xml得到(当刷机第一次重启或恢复出厂设置后重启时,该文件被生成,其中的值来自调用者对WallpaperManagerService.setDimensionHints的调用)。但是,第一次启动时,wallpaer_info.xml不存在,也就不采用其里面的值。这时,则采用的是getMaximumSizeDimension,也就是背景图的宽和高由getMaximumSizeDimension决定,代码如下:

// We always want to have some reasonable width hint.

WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);

Display d = wm.getDefaultDisplay();

int baseSize = d.getMaximumSizeDimension();

if (mWidth < baseSize) {

mWidth = baseSize;

}

if (mHeight < baseSize) {

mHeight = baseSize;

}

这有可能带来背景图不能充满整个屏幕的问题,因为ImageWallpaper.drawFrameLocked会根据surface大小来确定绘制背景:

SurfaceHolder sh = getSurfaceHolder();

final Rect frame = sh.getSurfaceFrame();

final int dw = frame.width();

final int dh = frame.height();

final int availw = dw - mBackgroundWidth;

final int availh = dh - mBackgroundHeight;

int xPixels = availw < 0 ? (int)(availw * mXOffset + .5f) : (availw / 2);

int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2);

其中mBackgroundWidth和mBackgroundHeight来自WallpaperManagerService中的两个函数getWidthHint和getHeightHint中的变量的值。笔者的一个工程样机的调试log输出如下:

11-27 09:43:20.030 2041 2041 D ImageWallpaper: dw=1080,dh=960,mBackgroundWidth=960,mBackgroundHeight=960,availw=120,availh=0,xPixels=60,yPixels=0,mXOffset=0.0,mYOffset=0.0

通过在WallpaperManagerService.loadSettingsLocked中改变其值的方式可以解决这一问题,但只能针对该产品,不具有普遍性:

diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java

index 4925a4e..79cb8b8 100644

--- a/services/java/com/android/server/WallpaperManagerService.java

+++ b/services/java/com/android/server/WallpaperManagerService.java

@@ -388,7 +388,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {

public void setDimensionHints(int width, int height) throws RemoteException {

checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);

-

+ Slog.d(“@BillYang_ycg”, “setDimensionHints: width=”+width+”,height=”+height);

if (width }

@@ -809,7 +809,12 @@ class WallpaperManagerService extends IWallpaperManager.Stub {

Display d = wm.getDefaultDisplay();

int baseSize = d.getMaximumSizeDimension();

if (mWidth < baseSize) {

– mWidth = baseSize;

+ //The width of background paper is not correct if use getMaximumSizeDimension

+ // when first time boot after factory reset: wallpaper dose not cover the whole screen

+ //Here I hacked it to correct this issue. Added by @BillYang_ycg, Nov 27 2012

+ int w = d.getRawWidth()*2;

+ Slog.d(“@BillYang_ycg”,”mWidth=”+w);

+ mWidth = w;

}

if (mHeight < baseSize) {

mHeight = baseSize;

以上代码基于Android 4.4.4 分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android设置桌面壁纸及恢复默认墙纸,程序中将创建一个存储壁纸图片资源的id数组,定义被选中的图片在id数组中的索引,需要自定义一个BaseAdapter,然后:   ImageView iv = new ImageView(Sample_12_2.this);//新建一个ImageView   iv.setBackgroundResource(imgIds[position]);//设置ImageView的背景图片   iv.setScaleType(ImageView.ScaleType.CENTER_CROP);   iv.setLayoutParams(new Gallery.LayoutParams(120, 120));//设置相框中元素的大小   将设置壁纸和恢复壁纸的功能写入按钮监听事件中,通过单击按钮来激活这两个功能:   设置ImageView为当前墙纸:   Button btnGetWall = (Button)findViewById(R.id.getWall);//获得Button对象   btnGetWall.setOnClickListener(new View.OnClickListener() {//为Button添加OnClickListener监听器   @Override   public void onClick(View v) {    ImageView iv = (ImageView)findViewById(R.id.currWall);    iv.setBackgroundDrawable(getWallpaper()); //设置ImageView显示的内容为当前墙纸   }   恢复默认壁纸:   setContentView(R.layout.main);//设置当前屏幕   Button btnClearWall = (Button)findViewById(R.id.clearWall);//获得Button对象   btnClearWall.setOnClickListener(new View.OnClickListener() {//添加OnClickListener监听器   @Override   public void onClick(View v) {//重写onClick方法   try {    Sample_12_2.this.clearWallpaper();//还原手机壁纸   } catch (IOException e) {//捕获并打印异常    e.printStackTrace();   }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值