新浪微博Android客戶端夜間模式是如何實現的?

也就是如何將主題包獨立為另一個程序。

補充兩點:
1、題主問的是Android,不是iOS,不是WP,也不是塞班;
2、題主問的是新浪微博,不是知乎,不是QQ,也不是微信。


2015/11/2 19:03更新

找同事要了工程,測試後發現就算shareduserid不一樣,照樣可以獲取到資源。

= =!。。。

看來還是要親自動手試試。。。

獲取Context和資源的方法看請看提問者自己的回答,已經說得很明白了,我就不重複了。

--------------------------------------------------------------------------------------------------------------------------------------
2015/11/2 11:21更新
之前回答有一個錯誤,回答說要shareduserid 和包名都相同才行,被StephenLee指出來了,謝謝。

只要shaerduserid相同即可(這裡寫錯了,shareduserid不同也可以),晚點我會上驗證代碼。

--------------------------------------------------------------------------------------------------------------------------------------

這周四,我們組的妹紙才分享了Android換膚機制的實現方式。

先不展開細說,說說機制吧。

我們知道Android中的布局都是在xml裡面定義的,那我們可以預先定義好很多個theme,然後只需要重新setTheme即可。(Activity需要重啟)

不過這種方式是主題內置的,打包好後就不能改動了。

而微博是通過把主題資源存放於APK的形式,然後通過下載到SD卡,讓用戶安裝實現換膚。

主題apk和微博apk之間shared user id要相同。 這樣安裝完成後,擁有同一個shared user id的多個APK可以配置成運行在同一個進程中,所以默認就是可以互相訪問任意數據。

所以我們可以在微薄應用中去得到主題APK的Context對象,然後通過Context.getResources()方法就可以獲得資源了。

我說的比較粗略,道理大概是這樣,這只是換膚的其中一種機制,還有一種是不需要安裝,直接從SD卡讀取資源。


感謝 @麵條提供的思路,題主補充幾點:
1、如何獲取另一個package的Context對象:

public static Context getPackageContext(Context context, String packageName) {
try {
return context.createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return null;
}

2、知道資源名稱如何獲取資源ID:

public static int getResourceId(Context context, String type, String name) {
return context.getResources().getIdentifier(name, type, context.getPackageName());
}

其中的Context對象就是上面獲取的packageContext,type為資源類型,包括"string","drawable","style"等。

3、關於android:sharedUserId和簽名:

同時主題apk和微博apk之間shared user id都相同,並且都用相同的簽名。

@麵條 這裡貌似不太正確,下面是反編譯出的主題包AndroidManifest.xml文件:

&
&

&

&

裡面沒有添加android:sharedUserId。另外,我的測試程序與微博的sharedUserId和簽名都不一樣,依然可以獲取到微博中的資源:

&找朋友&


我來回答如何實現黑夜模式吧。
之前也用過一些閱讀類的應用,也有黑夜模式功能,不過是偽黑夜模式,就是讓屏幕變暗一點。真正的黑夜模式,應該是定義成一種主題, 在這種主題下,用來顯示昵稱的TextView的字體顏色可能就是#2f2f2f, 對應的白天模式下的主題,這個顏色值或許可以是#b1b1b1。

那麼這是怎麼做到的呢?

首先我們可以定義一個白天模式和夜間模式的主題theme_day, theme_night.

&