GVKun编程网logo

您是否在任何项目中使用过PhantomReference?

13

对于想了解您是否在任何项目中使用过PhantomReference?的读者,本文将是一篇不可错过的文章,并且为您提供关于AndroidQ中不推荐使用PreferenceManagergetDefaul

对于想了解您是否在任何项目中使用过PhantomReference?的读者,本文将是一篇不可错过的文章,并且为您提供关于Android Q 中不推荐使用 PreferenceManager getDefaultSharedPreferences、android – addPreferencesFromResource使sharedPreferences不起作用、android – PreferenceManager.getDefaultSharedPreferences()vs getPreferences()、android – SharedPreferences ListPreference NullPointerException的有价值信息。

本文目录一览:

您是否在任何项目中使用过PhantomReference?

您是否在任何项目中使用过PhantomReference?

我唯一了解的PhantomReference

  • 如果使用其 get() 方法,它将始终返回null而不是对象。它有什么用?
  • 通过使用PhantomReference,您可以确保无法从 finalize 方法中恢复该对象。

但是这个概念/类的用途是什么?

您是否曾在您的任何项目中使用过此功能,或者在任何示例中应使用此功能?

答案1

小编典典

PhantomReference在简单,非常专业的内存分析器中使用s来监视对象的创建和销毁。我需要他们追踪破坏。但是这种方法已经过时了。(它于2004年针对J2SE1.4编写。)专业的分析工具功能更强大,更可靠,并且JMX或代理和JVMTI等新的Java 5功能也可以用于此目的。

PhantomReferences(始终与Reference队列一起使用)优于s,finalize但存在一些问题,因此应避免使用。主要是使对象再次可达。这可以通过终结器保护语来避免(->在’EffectiveJava’中了解更多信息)。因此它们也是 新的定稿

此外,PhantomReferences

使您可以准确确定何时从内存中删除对象。实际上,它们是确定这一点的唯一方法。通常这没有什么用处,但是在某些非常特殊的情况下(例如处理大图像)可能会派上用场:如果您确定应该对图像进行垃圾回收,则可以等到它实际加载后再尝试加载下一个图像,因此避免发生可怕的OutOfMemoryError的可能性。(引自尼古拉斯。)

就像psd首先写的那样,罗迪·格林(RoedyGreen)有很好的参考文献摘要。

Android Q 中不推荐使用 PreferenceManager getDefaultSharedPreferences

Android Q 中不推荐使用 PreferenceManager getDefaultSharedPreferences

PreferenceManager getDefaultSharedPreferences在Android
10中已弃用。我该如何更换它?

答案1

小编典典

可以使用PreferenceManagerieandroidx.preference.PreferenceManager
not的 Android 10 支持库版本android.preference.PreferenceManager

请记住将以下内容添加到您的 build.gradle

implementation ''androidx.preference:preference:1.1.1''

android – addPreferencesFromResource使sharedPreferences不起作用

android – addPreferencesFromResource使sharedPreferences不起作用

所以可能是另一个新的问题:)

我有一个Activity,一个appwidgetprovider和一个PreferenceActivity.在PreferenceActivity中我有一个ListPreference,我用它来定义小部件的文本大小.主活动启动时,sharedPreferences加载时没有任何问题,但是一旦运行PreferenceActivity,我就无法再在主活动中正确检索sharedPreference值.我尝试直接在PreferenceActivity中检索sharedPreference值并发生同样的事情:出于某种原因,当我尝试从sharedPreferences获取值时,我调用addPreferencesFromresource(R.drawable.settings); (在评论’测试1′),它说:

“onStart() 1, size: small” and “Small works!”

即有用.但是当我尝试在资源调用之后检索值时(在评论’测试2′),它说:

“onStart() 2, size: small” and “It doesn’t work …”

即它不起作用.我不知道为什么.显然它获得了sharedPreference的值,因为它表示当前的textWidgetSize在两种情况下都等于“small”,但由于某种原因,它在资源调用之后并不认为“small”=“small”.你们有什么想法吗?

这是PreferenceActivity代码:

package dk.mfoller.android.basicnote;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.widget.Toast;
import dk.mfoller.android.basicnote.R;

public class BasicNoteSettings extends PreferenceActivity{

    String widgetTextSize = "small";
    boolean widgetLineCounter = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Calls a function to get the preferences
        getPrefs();

        // Test 1
        maketoast("onStart() 1, size: " + widgetTextSize);
        if(widgetTextSize == "small") {
            maketoast("Small works!");
        } else if(widgetTextSize == "medium") {
            maketoast("Medium works!");
        } else if(widgetTextSize == "large") {
            maketoast("Large works!");
        } else {
            maketoast("It doesn't work ...");
        }

        // Gets the preference layout from xml
        addPreferencesFromresource(R.drawable.settings);

        // Calls a function to get the preferences
        getPrefs();

        // Test 2
        maketoast("onStart() 2, size: " + widgetTextSize);
        if(widgetTextSize == "small") {
            maketoast("Small works!");
        } else if(widgetTextSize == "medium") {
            maketoast("Medium works!");
        } else if(widgetTextSize == "large") {
            maketoast("Large works!");
        } else {
            maketoast("It doesn't work ...");
        }

    }

    // A function to get the preferences    
    private void getPrefs() {
        // Gets data from the shared preferences
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        widgetTextSize = prefs.getString("text_size_list", "small");
        widgetLineCounter = prefs.getBoolean("line_counter_cBox", true);
    }

    // A function to display a popup
    private void maketoast(String popup) {
        Toast.makeText(this, popup, Toast.LENGTH_SHORT).show();
    }

}

这是xml文档:

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="basicnote_settings"
    android:title="@string/settings_label">

    <PreferenceCategory android:title="Text size">
        <ListPreference android:key="text_size_list"
        android:title="Widget text size"
        android:summary="@string/text_size_summary"
        android:entries="@array/text_size_options"
        android:entryValues="@array/text_size_values"
        android:defaultValue="small" />
    </PreferenceCategory>

    <PreferenceCategory android:title="Other settings">
        <CheckBoxPreference android:key="line_counter_cBox"
            android:title="Line counter"
            android:summary="@string/hidden_lines_summary"
            android:defaultValue="true" />
    </PreferenceCategory>

</PreferenceScreen>

这是我的资源字符串:

<?xml version="1.0" encoding="utf-8"?>

<!-- Defines varIoUs resources -->
<resources>
    <string name="app_name">basicNote</string>
    <string name="note_hint">Tap to add some notes ...</string>
    <string name="fake_load">Loading notes ...</string>

    <string name="settings_label">basicNote settings</string>

    <string name="text_size_summary">Set the size of the widget text</string>
    <string-array name="text_size_options">
        <item>Small (12sp)</item>
        <item>Medium (13sp)</item>
        <item>Large (15sp)</item>
    </string-array>
    <string-array name="text_size_values">
        <item>small</item>
        <item>medium</item>
        <item>large</item>
    </string-array>

    <string name="hidden_lines_summary">Show/hide the number of lines not shown in the widget</string>
</resources>

解决方法:

您在String对象上使用==.请改用.equals(yourString).

android – PreferenceManager.getDefaultSharedPreferences()vs getPreferences()

android – PreferenceManager.getDefaultSharedPreferences()vs getPreferences()

PreferenceManager.getDefaultSharedPreferences(context)

getPreferences()

似乎检索不同的首选项.

PreferenceManager.getDefaultSharedPreferences(context).getBoolean(
                        "userWasAskedToEnableGps", false);

对我来说,返回false,

getPreferences(MODE_PRIVATE).getBoolean("userWasAskedToEnableGps", false);

返回true.

Preference是用编辑器编写的

Editor e = getPreferences(MODE_PRIVATE).edit(); 
e.putBoolean (...);
e.commit();

如何在Context中的Activity之外获得相同的Preferences?

解决方法:

从android github repo(1),我们可以看到getPreferences除了使用当前类名调用getSharedPreferences方法之外什么都不做.

public SharedPreferences getPreferences( int mode ) {
    return getSharedPreferences( getLocalClassName(), mode );
}

没有什么限制其他活动/代码使用适当的类名访问共享首选项.更重要的是,我不想使用getPreferences,因为这意味着=>永远不会更改活动名称.如果更改,则使用明确提及的早期类名称(升级前)来处理访问共享首选项.

android – SharedPreferences ListPreference NullPointerException

android – SharedPreferences ListPreference NullPointerException

我正在尝试在我的首选项xml中设置频率列表,但我一直收到此错误.我也附上了所有相关文件.我相信我正确设置了值,但我找不到我的错误当前的位置.另外,当我使用SharedPreferences.getString(key,defaultValue)时返回什么值? ENTRY或ENTRYVALUE?

我的错误:

08-20 00:14:25.195: E/AndroidRuntime(1260): FATAL EXCEPTION: main
08-20 00:14:25.195: E/AndroidRuntime(1260): java.lang.NullPointerException
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.preference.ListPreference.findindexOfValue(ListPreference.java:215)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.preference.ListPreference.getValueIndex(ListPreference.java:224)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.preference.ListPreference.getEntry(ListPreference.java:202)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.preference.ListPreference.getSummary(ListPreference.java:148)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.preference.Preference.onBindView(Preference.java:515)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.preference.Preference.getView(Preference.java:453)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.preference.PreferenceGroupAdapter.getView(PreferenceGroupAdapter.java:222)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.AbsListView.obtainView(AbsListView.java:2461)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.ListView.makeAndAddView(ListView.java:1775)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.ListView.fillDown(ListView.java:678)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.ListView.fillFromTop(ListView.java:739)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.ListView.layoutChildren(ListView.java:1628)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.AbsListView.onLayout(AbsListView.java:2296)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.View.layout(View.java:14063)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.ViewGroup.layout(ViewGroup.java:4603)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1655)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1513)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.LinearLayout.onLayout(LinearLayout.java:1426)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.View.layout(View.java:14063)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.ViewGroup.layout(ViewGroup.java:4603)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.View.layout(View.java:14063)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.ViewGroup.layout(ViewGroup.java:4603)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1655)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1513)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.LinearLayout.onLayout(LinearLayout.java:1426)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.View.layout(View.java:14063)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.ViewGroup.layout(ViewGroup.java:4603)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.View.layout(View.java:14063)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.ViewGroup.layout(ViewGroup.java:4603)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.ViewRootImpl.performlayout(ViewRootImpl.java:1994)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1815)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1112)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4518)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.Choreographer.doCallbacks(Choreographer.java:555)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.Choreographer.doFrame(Choreographer.java:525)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.view.Choreographer$FramedisplayEventReceiver.run(Choreographer.java:711)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.os.Handler.handleCallback(Handler.java:615)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.os.Handler.dispatchMessage(Handler.java:92)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.os.Looper.loop(Looper.java:137)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at android.app.ActivityThread.main(ActivityThread.java:4898)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at java.lang.reflect.Method.invokeNative(Native Method)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at java.lang.reflect.Method.invoke(Method.java:511)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
08-20 00:14:25.195: E/AndroidRuntime(1260):     at dalvik.system.NativeStart.main(Native Method)

xml布局:

<ListPreference 
        android:key="frequency_key"
        android:title="Sample Rate"
        android:defaultValue="8000"
        android:entries="@array/freq_titles"
        android:entryValues="@array/freq_values"
        />

xml数组:

<?xml version="1.0" encoding="utf-8"?>
<resources>

<string-array name="freq_titles">
    <item name="8000">8k Hz</item>
    <item name="16000">16k Hz</item>
    <item name="22050">22.05k Hz</item>
    <item name="44100">44.1k Hz</item>
    <item name="48000">48k Hz</item>
</string-array>

<array name="freq_values">
    <item name="8000">8000</item>
    <item name="16000">16000</item>
    <item name="22050">22050</item>
    <item name="44100">44100</item>
    <item name="48000">48000</item>
</array>

</resources>

更新:即使我从默认的共享首选项中执行getAll(),它也很奇怪,它向我显示“frequency_key = 8k Hz”.所以它已经初始化了.

来自我的偏好类的更多代码:

public class Settings_ActivityAH extends PreferenceFragment implements OnSharedPreferencechangelistener{
private SharedPreferences prefs;
private Preference myAccountName;
private Preference myGoogleUsername;
private Preference myGooglePassword;
private static Context context;

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    addPreferencesFromresource(R.xml.preferences);
    context = getActivity();

    if (context == null){
        Log.e("error","context is null");
    }


    prefs = PreferenceManager.getDefaultSharedPreferences(context);

    myAccountName = (Preference) findPreference("account_name_title_key");
    myGoogleUsername = (Preference) findPreference("googleusername_key");
    myGooglePassword = (Preference) findPreference("googlepassword_key");
    myAccountName.setSummary(prefs.getString("account_name_title_key", "none"));
    myGoogleUsername.setTitle("username: "+prefs.getString("googleusername_key", "none"));
    myGooglePassword.setTitle("password: "+prefs.getString("googlepassword_key", "none"));
    Log.e("Check prefs",prefs.getAll().toString());
    prefs.registerOnSharedPreferencechangelistener(this);

}

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
        String key) {
    Log.e("in onSharedPref","yea");
    Preference preference = findPreference(key);

    if (preference.getClass() == EditTextPreference.class){
        Log.e("in editText Pref", "yeah");

        if( key.equals("account_name_title_key")){
            myAccountName.setSummary(sharedPreferences.getString("account_name_key","none"));
            Log.e("accountname prefs",sharedPreferences.getString("account_name_key","none"));
    }
        if( key.equals("account_name_key")){
            myAccountName.setSummary(sharedPreferences.getString("account_name_key","none"));
            Log.e("accountname prefs",sharedPreferences.getString("account_name_key","none"));
    }

    else if (preference.getClass() == PreferenceCategory.class){
        Log.e("in category Pref", "yeah");

        if (key.equals("googleusername_key")){
            myGoogleUsername.setTitle("Username: "+sharedPreferences.getString(key, "none"));
            Log.e("googleusername prefs",sharedPreferences.getString(key, "none"));

        }
        else if( key.equals("googlepassword_key")){
            myGooglePassword.setTitle("Password: "+sharedPreferences.getString(key, "none"));
            Log.e("googlepassword prefs",sharedPreferences.getString(key, "none"));

        }
    }

}
else{
    Log.e("insufficient key called","onSharedPreferenceChanged AH");
}

}

}

解决方法:

似乎Android只接受字符串数组作为ListPreference XML属性android:entryValues的参数.这与所有XML属性仅采用具有一种特定的预定类型(即int,bool,string等)的参数一致.请参阅以下问题:ListPreference: use string-array as Entry and integer-array as Entry Values doesn’t work

关于你的问题,getString()将返回与被点击的条目对应的android:entryValues数组的元素. android:entries数组仅用作用户的一系列显示字符串,并且在代码中没有其他影响,而android:entryValues中的值用于应用程序中的持久存储.

今天的关于您是否在任何项目中使用过PhantomReference?的分享已经结束,谢谢您的关注,如果想了解更多关于Android Q 中不推荐使用 PreferenceManager getDefaultSharedPreferences、android – addPreferencesFromResource使sharedPreferences不起作用、android – PreferenceManager.getDefaultSharedPreferences()vs getPreferences()、android – SharedPreferences ListPreference NullPointerException的相关知识,请在本站进行查询。

本文标签: