因為最近的項目我都要把程序的資源文件都放到另壹個apk中。而上面這個方法中只能傳本地的或系統的資源id。那麽我就找到了類似的方法:addPreferencesFromIntent(Intent
intent);百度goolge了壹下發現都是沒有這個方法的例子只有搜索google的裏面的api:
public
void addPreferencesFromIntent (Intent intent)
Since: API Level 1
This method is deprecated.
This function is
not relevant for a modern fragment-based PreferenceActivity.
Adds
preferences from activities that match the given Intent.
Parameters
intent
The Intent to query
activities.
這樣介紹就很簡單了,只是讓我們去查詢activities。沒有說明xml是什麽給的。沒辦法我只能去看源碼,看他們是什麽解析Intent的,那我就給出壹個可用的intent。
因為是繼承PreferenceFragment的,我就從源碼找到frameworks/base/core/java/android/preference/PreferenceFragment.java這個類:
view
plaincopy to clipboardprint?
<span style="white-space:pre"> </span>public void addPreferencesFromIntent(Intent intent) { requirePreferenceManager(); setPreferenceScreen(mPreferenceManager.inflateFromIntent(intent, getPreferenceScreen())); }
<span style="white-space:pre"> </span>public void addPreferencesFromIntent(Intent intent) { requirePreferenceManager(); setPreferenceScreen(mPreferenceManager.inflateFromIntent(intent, getPreferenceScreen())); }
然後這裏又用到了mPreferenceManager.inflateFromIntentt(intent,
getPreferenceScreen()),那麽在找到這個類frameworks/base/core/java/android/preference/PreferenceManager.java:
view
plaincopy to clipboardprint?
<span style="white-space:pre"> </span>PreferenceScreen inflateFromIntent(Intent queryIntent, PreferenceScreen rootPreferences) { final List<ResolveInfo> activities = queryIntentActivities(queryIntent); final HashSet<String> inflatedRes = new HashSet<String>(); for (int i = activities.size() - 1; i >= 0; i--) { final ActivityInfo activityInfo = activities.get(i).activityInfo; final Bundle metaData = activityInfo.metaData; if ((metaData == null) || !metaData.containsKey(METADATA_KEY_PREFERENCES)) { continue; } // Need to concat the package with res ID since the same res ID // can be re-used across contexts final String uniqueResId = activityInfo.packageName + ":" + activityInfo.metaData.getInt(METADATA_KEY_PREFERENCES); if (!inflatedRes.contains(uniqueResId)) { inflatedRes.add(uniqueResId); final Context context; try { context = mContext.createPackageContext(activityInfo.packageName, 0); } catch (NameNotFoundException e) { Log.w(TAG, "Could not create context for " + activityInfo.packageName + ": " + Log.getStackTraceString(e)); continue; } final PreferenceInflater inflater = new PreferenceInflater(context, this); final XmlResourceParser parser = activityInfo.loadXmlMetaData(context .getPackageManager(), METADATA_KEY_PREFERENCES); rootPreferences = (PreferenceScreen) inflater .inflate(parser, rootPreferences, true); parser.close(); } } rootPreferences.onAttachedToHierarchy(this); return rootPreferences; }
<span style="white-space:pre"> </span>PreferenceScreen inflateFromIntent(Intent queryIntent, PreferenceScreen rootPreferences) { final List<ResolveInfo> activities = queryIntentActivities(queryIntent); final HashSet<String> inflatedRes = new HashSet<String>(); for (int i = activities.size() - 1; i >= 0; i--) { final ActivityInfo activityInfo = activities.get(i).activityInfo; final Bundle metaData = activityInfo.metaData; if ((metaData == null) || !metaData.containsKey(METADATA_KEY_PREFERENCES)) { continue; } // Need to concat the package with res ID since the same res ID // can be re-used across contexts final String uniqueResId = activityInfo.packageName + ":" + activityInfo.metaData.getInt(METADATA_KEY_PREFERENCES); if (!inflatedRes.contains(uniqueResId)) { inflatedRes.add(uniqueResId); final Context context; try { context = mContext.createPackageContext(activityInfo.packageName, 0); } catch (NameNotFoundException e) { Log.w(TAG, "Could not create context for " + activityInfo.packageName + ": " + Log.getStackTraceString(e)); continue; } final PreferenceInflater inflater = new PreferenceInflater(context, this); final XmlResourceParser parser = activityInfo.loadXmlMetaData(context .getPackageManager(), METADATA_KEY_PREFERENCES); rootPreferences = (PreferenceScreen) inflater .inflate(parser, rootPreferences, true); parser.close(); } } rootPreferences.onAttachedToHierarchy(this); return rootPreferences; }
從上面的代碼我們就知道要從intent中獲取壹組activity。通過 activityInfo.metaData.getInt(METADATA_KEY_PREFERENCES)我們知道就是從activity拿的<meta-data
這些數據,那麽我們在AndroidManifest.xml中eclipse提示的<meta-data只有三個屬性:
那麽我麽就不難得出結論<meta-data 中的nane就是METADATA_KEY_PREFERENCES,而xml就是resource。
接下來還有壹個問題就是METADATA_KEY_PREFERENCES的值是多少。搜壹下在PreferenceManager.java中有如下定義:
view
plaincopy to clipboardprint?
public static final String METADATA_KEY_PREFERENCES = "android.preference";
public static final String METADATA_KEY_PREFERENCES = "android.preference";
知道了以上原理我們來驗證壹下:
新建壹個工程,在裏面的activity標簽中加<meta-data,如下:
view
plaincopy to clipboardprint?
<span style="white-space:pre"> </span><activity android:name="com.winca.style.defaultskin.RadioReadSettingXMLActivity" android:icon="@drawable/radio" android:label="@string/radio_app_name" > <meta-data android:name="android.preference" android:resource="@xml/setting_preference"/> </activity>
<span style="white-space:pre"> </span><activity android:name="com.winca.style.defaultskin.RadioReadSettingXMLActivity" android:icon="@drawable/radio" android:label="@string/radio_app_name" > <meta-data android:name="android.preference" android:resource="@xml/setting_preference"/> </activity>
這個xml就是從我們程序中拷貝多來放到新建的工程中的。
原來我們工程用的addPreferencesFromResource(R.xml.setting_preference);這語句,我們這樣替換:
view
plaincopy to clipboardprint?
<pre name="code" class="java"><span style="white-space:pre"> </span>Intent xmlIntent = new Intent(); ComponentName component = new ComponentName("com.winca.style.defaultskin","com.winca.style.defaultskin.RadioReadSettingXMLActivity"); xmlIntent.setComponent(component); addPreferencesFromIntent(xmlIntent);
<pre name="code" class="java"><span style="white-space:pre"> </span>Intent xmlIntent = new Intent(); ComponentName component = new ComponentName("com.winca.style.defaultskin","com.winca.style.defaultskin.RadioReadSettingXMLActivity"); xmlIntent.setComponent(component); addPreferencesFromIntent(xmlIntent);
運行壹下,正常顯示xml裏面的。問題解決。