Pergunta

Tenho algumas informações armazenadas como SharedPreferences.Preciso acessar essas informações fora de uma atividade (de uma classe de modelo de domínio).Então criei um método estático em uma Activity que uso apenas para obter as preferências compartilhadas.

Isso está me dando alguns problemas, pois aparentemente não é possível chamar o método "getSharedPreferences" a partir de um método estático.

Aqui está a mensagem que o eclipse está me dando:

Cannot make a static reference to the non-static method 
getSharedPreferences(String, int) from the type ContextWrapper

Tentei contornar isso usando uma instância de Activity, assim:

public static SharedPreferences getSharedPreferences () {
  Activity act = new Activity();
  return act.getSharedPreferences("FILE", 0);
}

Este código fornece uma exceção de ponto nulo.

Existe uma solução alternativa?Estou sentindo o cheiro do código do Android ao tentar fazer isso?

Desde já, obrigado.

Foi útil?

Solução

Isso porque neste caso, act é um objeto que você apenas cria. Você tem que deixar o Android fazer isso por você; getSharedPreferences() é um método de Context, (Activity, Service e outras classes se estende de Context). Então, você tem que fazer sua escolha:

  • Se o método estiver dentro de uma atividade ou outro tipo de contexto:

    getApplicationContext().getSharedPreferences("foo", 0);
    
  • Se o método estiver fora de uma atividade ou outro tipo de contexto:

    // you have to pass the context to it. In your case:
    // this is inside a public class
    public static SharedPreferences getSharedPreferences (Context ctxt) {
       return ctxt.getSharedPreferences("FILE", 0);
    }
    
    // and, this is in your activity
    YourClass.this.getSharedPreferences(YourClass.this.getApplicationContext());
    

Outras dicas

A resposta de Cristian é boa, mas se você quiser acessar suas preferências compartilhadas de todos os lugares da maneira certa: seria:

  1. Criar uma subclasse de Application, por exemplo public class MyApp extends Application {...
  2. Colocou o android:name atributo do seu <application> Tag no Androidmanifest.xml para apontar para sua nova classe, por exemplo android:name="MyApp" (então a classe é reconhecida pelo Android)
  3. No método onCreate () da sua instância do aplicativo, salve seu contexto (por exemplo, this) para um campo estático nomeado app e crie um método estático que retorne este campo, por exemplo getApp(). Você pode usar esse método posteriormente para obter um contexto do seu aplicativo e, portanto, obter suas preferências compartilhadas. :-)

Eu tive um problema semelhante e resolvi simplesmente passando o contexto atual para a função estática:

public static void LoadData(Context context)
{
    SharedPreferences SaveData = context.getSharedPreferences(FILENAME, MODE_PRIVATE);
    Variable = SaveData.getInt("Variable", 0);
    Variable1 = SaveData.getInt("Variable1", 0);
    Variable2 = SaveData.getInt("Variable2", 0);
}

Como você está ligando de fora de uma atividade, será necessário salvar o contexto:

public static Context context;

E dentro do OnCreate:

context = this;

Armazenar o contexto como uma variável estática pode causar problemas porque quando a classe é destruída, o mesmo ocorre com as variáveis ​​estáticas.Isso às vezes acontece quando o aplicativo é interrompido e fica com pouca memória.Apenas certifique-se de que o contexto esteja sempre definido antes de tentar usá-lo, mesmo quando a classe que define o contexto for destruída aleatoriamente.

Esta é uma alternativa melhor para armazenar suas preferências compartilhadas em campos estáticos.

  1. Semelhante ao que foi sugerido aqui, crie uma classe que estenda Application
  2. Faça com que o construtor da sua classe use Context como parâmetro.
  3. Use seu contexto para obter preferências compartilhadas e armazená-las em variáveis ​​privadas.
  4. Crie variáveis ​​públicas para retornar os dados recuperados.

por exemplo

public class UserInfo extends Application{
    private String SAVED_USERID;
    private String SAVED_USERNAME;

    public UserInfo(Context context) {
        SharedPreferences prefs = context.getSharedPreferences(FILE, MODE_PRIVATE);
        SAVED_USERNAME = prefs.getString("UserName", null);
        SAVED_USERID = prefs.getString("UserID", null);
    }

    public String getSavedUserName() {
        return SAVED_USERNAME;
    }

    public String getSavedUserID() {
         return SAVED_USERID;
    }
}

uso em sua atividade

   UserInfo user = new UserInfo(this.getApplicationContext());

   String SAVED_USERNAME = user.getSavedUserName();
   String SAVED_USERID = user.getSavedUserID();

Eu tinha a mesma necessidade – algumas das minhas preferências precisam ser acessadas com frequência e de forma eficiente.Também imagino que ler e escrever uma string em SharedPreferences seja um pouco mais lento do que obter e definir uma variável estática (mas provavelmente em um grau insignificante).Eu também me acostumei a usar campos estáticos, recuperando valores de preferência apenas na inicialização e salvando-os ao fechar.

Não adorei minhas opções para manter referências estáticas diretamente aos SharedPreferences/contextos, mas até agora essa solução alternativa foi suficiente.

Minha solução:

  1. Crie uma classe Configurações com todas as variáveis ​​estáticas necessárias.

  2. Quando o aplicativo for inicializado, recupere os campos SharedPreferences e defina imediatamente todos os campos Configurações (eu chamo um método "loadSharedPrefs()" no final do método onCreate de MainActivity).

  3. Na inicialização do preferChangeListener de SettingsActivity, defina o campo estático apropriado na classe Configurações.(Eu chamo um método "setAppropriateSetting (key, value)" no início do onPreferenceChange () de SettingsActivity).

Use suas preferências estáticas onde e quando quiser!

public static String getPreferenceValue(Context context) {
    SharedPreferences sharedPreferences = 
        PreferenceManager.getDefaultSharedPreferences(context);
    String key = context.getString(R.string.pref_key);
    String defaultVal = context.getString(R.string.pref_default);
    return sharedPreferences.getString(key,defaulVal);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top