xxha@xxha-OptiPlex-780:~/work/kunlun0112$ cd packages/wallpapers/
xxha@xxha-OptiPlex-780:~/work/kunlun0112/packages/wallpapers$ls
Basic LivePicker MagicSmoke MusicVisualization
这里有关系的是Basic 和 LivePicker.
xxha@xxha-OptiPlex-780:~/work/kunlun0112/packages/wallpapers$ cd Basic
xxha@xxha-OptiPlex-780:~/work/kunlun0112/packages/wallpapers/Basic$ ls
AndroidManifest.xml Android.mk MODULE_LICENSE_APACHE2 NOTICE res src
看src里的代码:
xxha@xxha-OptiPlex-780:~/work/kunlun0112/packages/wallpapers/Basic$ vim src/com/android/wallpaper/polarclock/PolarClockWallpaper.java
这是极地时钟程序运行的代码。
里面个ClockPalette:
static abstract class ClockPalette {
public static ClockPalette parseXmlPaletteTag(XmlResourceParser xrp) {
String kind = xrp.getAttributeValue(null, "kind");
if ("cycling".equals(kind)) {
return CyclingClockPalette.parseXmlPaletteTag(xrp);
} else {
return FixedClockPalette.parseXmlPaletteTag(xrp);
}
}
public abstract int getBackgroundColor();
public abstract int getSecondColor(float forAngle);
public abstract int getMinuteColor(float forAngle);
public abstract int getHourColor(float forAngle);
public abstract int getDayColor(float forAngle);
public abstract int getMonthColor(float forAngle);
public abstract String getId();
}
这里调用了2个函数
CyclingClockPalette.parseXmlPaletteTag(xrp) 和
FixedClockPalette.parseXmlPaletteTag(xrp)
FixedClockPalette 定义如下:
static class FixedClockPalette extends ClockPalette {
protected String mId;
protected int mBackgroundColor;
protected int mSecondColor;
protected int mMinuteColor;
protected int mHourColor;
protected int mDayColor;
protected int mMonthColor;
private static FixedClockPalette sFallbackPalette = null;
public static FixedClockPalette getFallback() {
if (sFallbackPalette == null) {
sFallbackPalette = new FixedClockPalette();
sFallbackPalette.mId = "default";
sFallbackPalette.mBackgroundColor = Color.WHITE;
sFallbackPalette.mSecondColor =
sFallbackPalette.mMinuteColor =
sFallbackPalette.mHourColor =
sFallbackPalette.mDayColor =
sFallbackPalette.mMonthColor =
Color.BLACK;
}
return sFallbackPalette;
}
private FixedClockPalette() { }
public static ClockPalette parseXmlPaletteTag(XmlResourceParser xrp) {
final FixedClockPalette pal = new FixedClockPalette();
pal.mId = xrp.getAttributeValue(null, "id");
String val;
if ((val = xrp.getAttributeValue(null, "background")) != null)
pal.mBackgroundColor = Color.parseColor(val);
if ((val = xrp.getAttributeValue(null, "second")) != null)
pal.mSecondColor = Color.parseColor(val);
if ((val = xrp.getAttributeValue(null, "minute")) != null)
pal.mMinuteColor = Color.parseColor(val);
if ((val = xrp.getAttributeValue(null, "hour")) != null)
pal.mHourColor = Color.parseColor(val);
if ((val = xrp.getAttributeValue(null, "day")) != null)
pal.mDayColor = Color.parseColor(val);
if ((val = xrp.getAttributeValue(null, "month")) != null)
pal.mMonthColor = Color.parseColor(val);
return (pal.mId == null) ? null : pal;
}
@Override
public int getBackgroundColor() {
return mBackgroundColor;
}
@Override
public int getSecondColor(float forAngle) {
return mSecondColor;
}
@Override
public int getMinuteColor(float forAngle) {
return mMinuteColor;
}
@Override
public int getHourColor(float forAngle) {
return mHourColor;
}
@Override
public int getDayColor(float forAngle) {
return mDayColor;
}
@Override
public int getMonthColor(float forAngle) {
return mMonthColor;
}
@Override
public String getId() {
return mId;
}
}
CyclingClockPalette 定义如下:
static class CyclingClockPalette extends ClockPalette {
protected String mId;
protected int mBackgroundColor;
protected float mSaturation;
protected float mBrightness;
private static final int COLORS_CACHE_COUNT = 720;
private final int[] mColors = new int[COLORS_CACHE_COUNT];
private static CyclingClockPalette sFallbackPalette = null;
public static CyclingClockPalette getFallback() {
if (sFallbackPalette == null) {
sFallbackPalette = new CyclingClockPalette();
sFallbackPalette.mId = "default_c";
sFallbackPalette.mBackgroundColor = Color.WHITE;
sFallbackPalette.mSaturation = 0.8f;
sFallbackPalette.mBrightness = 0.9f;
sFallbackPalette.computeIntermediateColors();
}
return sFallbackPalette;
}
private CyclingClockPalette() { }
private void computeIntermediateColors() {
final int[] colors = mColors;
final int count = colors.length;
float invCount = 1.0f / (float) COLORS_CACHE_COUNT;
for (int i = 0; i < count; i++) {
colors[i] = Color.HSBtoColor(i * invCount, mSaturation, mBrightness);
}
}
public static ClockPalette parseXmlPaletteTag(XmlResourceParser xrp) {
final CyclingClockPalette pal = new CyclingClockPalette();
pal.mId = xrp.getAttributeValue(null, "id");
String val;
if ((val = xrp.getAttributeValue(null, "background")) != null)
pal.mBackgroundColor = Color.parseColor(val);
if ((val = xrp.getAttributeValue(null, "saturation")) != null)
pal.mSaturation = Float.parseFloat(val);
if ((val = xrp.getAttributeValue(null, "brightness")) != null)
pal.mBrightness = Float.parseFloat(val);
if (pal.mId == null) {
return null;
} else {
pal.computeIntermediateColors();
return pal;
}
}
@Override
public int getBackgroundColor() {
return mBackgroundColor;
}
@Override
public int getSecondColor(float forAngle) {
return mColors[((int) (forAngle * COLORS_CACHE_COUNT))];
}
@Override
public int getMinuteColor(float forAngle) {
return mColors[((int) (forAngle * COLORS_CACHE_COUNT))];
}
@Override
public int getHourColor(float forAngle) {
return mColors[((int) (forAngle * COLORS_CACHE_COUNT))];
}
@Override
public int getDayColor(float forAngle) {
return mColors[((int) (forAngle * COLORS_CACHE_COUNT))];
}
@Override
public int getMonthColor(float forAngle) {
return mColors[((int) (forAngle * COLORS_CACHE_COUNT))];
}
@Override
public String getId() {
return mId;
}
}
定义完了调色板,接着就是画图的引擎了,ClockEngine
class ClockEngine extends Engine implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final float SMALL_RING_THICKNESS = 8.0f;
private static final float MEDIUM_RING_THICKNESS = 16.0f;
private static final float LARGE_RING_THICKNESS = 32.0f;
private static final float DEFAULT_RING_THICKNESS = 24.0f;
private static final float SMALL_GAP = 14.0f;
private static final float LARGE_GAP = 38.0f;
private final HashMap<String, ClockPalette> mPalettes = new HashMap<String, ClockPalette>();
private ClockPalette mPalette;
private SharedPreferences mPrefs;
private boolean mShowSeconds;
private boolean mVariableLineWidth;
private boolean mWatcherRegistered;
private float mStartTime;
private Time mCalendar;
private final Paint mPaint = new Paint();
private final RectF mRect = new RectF();
private float mOffsetX;
private final BroadcastReceiver mWatcher = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
final String timeZone = intent.getStringExtra("time-zone");
mCalendar = new Time(TimeZone.getTimeZone(timeZone).getID());
drawFrame();
}
};
private final Runnable mDrawClock = new Runnable() {
public void run() {
drawFrame();
}
};
private boolean mVisible;
ClockEngine() {
XmlResourceParser xrp = getResources().getXml(R.xml.polar_clock_palettes);
try {
int what = xrp.getEventType();
while (what != END_DOCUMENT) {
if (what == START_TAG) {
if ("palette".equals(xrp.getName())) {
ClockPalette pal = ClockPalette.parseXmlPaletteTag(xrp);
if (pal.getId() != null) {
mPalettes.put(pal.getId(), pal);
}
}
}
what = xrp.next();
}
} catch (IOException e) {
Log.e(LOG_TAG, "An error occured during wallpaper configuration:", e);
} catch (XmlPullParserException e) {
Log.e(LOG_TAG, "An error occured during wallpaper configuration:", e);
} finally {
xrp.close();
}
mPalette = CyclingClockPalette.getFallback();
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
mPrefs = PolarClockWallpaper.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
mPrefs.registerOnSharedPreferenceChangeListener(this);
// load up user's settings
onSharedPreferenceChanged(mPrefs, null);
mCalendar = new Time();
mCalendar.setToNow();
mStartTime = mCalendar.second * 1000.0f;
final Paint paint = mPaint;
paint.setAntiAlias(true);
paint.setStrokeWidth(DEFAULT_RING_THICKNESS);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStyle(Paint.Style.STROKE);
if (isPreview()) {
mOffsetX = 0.5f;
}
}
...
值得一提的是JAVA与XML之间的交互。
这里的res里有很多xml文件,重要的有
xxha@xxha-OptiPlex-780:~/work/kunlun0112/packages/wallpapers/Basic$ vim res/values/strings.xml
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- General -->
<skip />
<!-- Application name -->
<string name="wallpapers">Android Live Wallpapers</string>
<!-- Wallpapers: -->
<skip />
<!-- Wallpaper showing the camera preview -->
<string name="wallpaper_walkaround">See Through</string>
<string name="wallpaper_walkaround_author">Google</string>
<string name="wallpaper_walkaround_desc">
See through your phone and walk around without risking accidents.
</string>
<!-- Wallpaper showing grass and the sky -->
<string name="wallpaper_grass">Grass</string>
<string name="wallpaper_grass_author">Google</string>
<string name="wallpaper_grass_desc">
Blades of grass wave gently in front of a day or night sky.
</string>
<!-- Wallpaper showing a galaxy -->
<string name="wallpaper_galaxy">Galaxy</string>
<string name="wallpaper_galaxy_author">Google</string>
<string name="wallpaper_galaxy_desc">
A galaxy made of slowly swirling stars.
</string>
<!-- Wallpaper showing leaves floating on water -->
<string name="wallpaper_fall">Water</string>
<string name="wallpaper_fall_author">Google</string>
<string name="wallpaper_fall_desc">
Autumn leaves tumble<br>
To the rippling pond below:<br>
Liquid background Zen
</string>
<!-- Wallpaper showing a clock -->
<string name="wallpaper_clock">Polar clock</string>
<string name="wallpaper_clock_author">Google</string>
<string name="wallpaper_clock_desc">
Presents the date and time as clockwise arcs: month,
day, hour, minute, and second.
</string>
<!-- Wallpaper showing nexus -->
<string name="wallpaper_nexus">Nexus</string>
<string name="wallpaper_nexus_author">Google</string>
<string name="wallpaper_nexus_desc">
A peek inside the neural network.
</string>
<!-- Polar clock: title of settings activity -->
<string name="clock_settings">Polar clock settings</string>
<!-- Polar clock: label for "show seconds" pref -->
<string name="show_seconds">Show seconds</string>
<!-- Polar clock: label for "variable widths" pref -->
<string name="variable_line_width">Vary ring widths</string>
<!-- Polar clock: label for "palette" pref -->
<string name="palette">Color palette</string>
<!-- Polar clock: palette name -->
<string name="palette_gray">Iron</string>
<!-- Polar clock: palette name -->
<string name="palette_violet">Midnight</string>
<!-- Polar clock: palette name -->
<string name="palette_matrix">Green Screen</string>
<!-- Polar clock: palette name -->
<string name="palette_white_c">Polar Bear (dynamic)</string>
<!-- Polar clock: palette name -->
<string name="palette_black_c">Black Hole (dynamic)</string>
<!-- Polar clock: palette name -->
<string name="palette_halloween">Pumpkin Pie</string>
<!-- Polar clock: palette name -->
<string name="palette_zenburn">Alien Fruit Salad</string>
<!-- Polar clock: palette name -->
<string name="palette_oceanic">Blue Laser</string>
</resources>
编译的时候,编译器会把.xml里的资源编译成R里面的常量。如
out/target/common/R/。。。
我想这就是android 应用层编程的架构了。
这里的Bug问题是跟LCD 分辨率有关系,日和月cycle没有显示