Android getter setter возвращает нулевые данные?

У меня есть один класс ApplicationDetails с методами получения и установки.

public class ApplicationDetails {
    String supportURL;
    String companyURL;
    String copyRightText;

    // with getter and setter methods 

}

Я устанавливаю все данные в своей активности на заставке.

ApplicationDetails appDetails = new ApplicationDetails();
String supportURL = getResources().getString(R.string.support_url);
appDetails.setSupportURL(supportURL);

Для примера я просто устанавливаю данные из строкового файла, но в приложении они поступают из разных источников.

Но когда я пытался получить доступ к данным в другом действии, он возвращает нулевое значение. например

public class AboutViewController extends Activity {

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

        ApplicationDetails appDetails = new ApplicationDetails();
        System.out.println(" app support url " + appDetails.getSupportURL());
    }

}

выход

I/System.out(2242):  app support url null

любая помощь.


person Mac    schedule 21.01.2013    source источник
comment
Вы создаете новый объект ApplicationDetails и читаете его. Конечно он будет иметь значения по умолчанию, а не те, которые вы ранее установили для совершенно другого объекта.   -  person Joachim Sauer    schedule 21.01.2013
comment
вам нужно немного узнать о java, oop и программировании в целом, прежде чем пытаться делать такие вещи.   -  person njzk2    schedule 21.01.2013
comment
вы можете достичь своей цели с помощью класса синглтона theserverside.de/singleton-pattern-in- Java   -  person Mario    schedule 21.01.2013


Ответы (5)


Вы получаете null, потому что вы создаете новый объект, и все поля инициализируются нулем.

В вашем случае я вижу, что эти поля будут одинаковыми через приложение, поэтому вы можете использовать Singleton шаблон и создайте экземпляр только одного объекта для вашего приложения и обратитесь к нему позже. Вам не нужно создавать новый объект каждый раз, когда вы к нему обращаетесь. Это было бы нормально для этого класса, и вы также можете сделать их константами. (Я предполагаю, что эти переменные не изменятся при выполнении)

person Taras Leskiv    schedule 21.01.2013

В качестве быстрого решения вы можете сделать свой объект supportURL статическим, но это не очень хорошее решение.

public class ApplicationDetails {
static String supportURL;
static String companyURL;
static String copyRightText;

// with getter and setter methods 

}

лучшим решением является передача строк из одного действия в другое с намерениями, когда вы начинаете свое действие AboutViewController.

person Aram    schedule 21.01.2013

Вы можете использовать общую настройку для хранения данных, которые будут использоваться в вашем приложении. Здесь контекст в конструкторе — это не что иное, как ваша активность.

public class ApplicationDetails {

        public static final String SUPPORT_URL = "support_url"; 
        public static final String COMPANY_URL = "company_url";
        public static final String COPYRIGHT_URL = "copyright_url";

        String supportURL;
        String companyURL;
        String copyRightText;
        private Context context;

        public ApplicationDetails(Context context) {
            super();
            this.context = context;
        }

        private String getPreference(String key)
        {
            return PreferenceManager.getDefaultSharedPreferences(context).getString(key, null);
        }

        private void setPreference(String key, String value)
        {
            PreferenceManager.getDefaultSharedPreferences(context).edit().putString(key, value).commit();
        }

        public String getSupportURL() {
            if(supportURL == null)
                supportURL = getPreference(SUPPORT_URL);
            return supportURL;
        }

        public void setSupportURL(String supportURL) {
            this.supportURL = supportURL;
            setPreference(SUPPORT_URL, supportURL);
        }

        public String getCompanyURL() {
            if(supportURL == null)
                supportURL = getPreference(COMPANY_URL);
            return companyURL;
        }

        public void setCompanyURL(String companyURL) {
            this.companyURL = companyURL;
            setPreference(COMPANY_URL, companyURL);
        }

        public String getCopyRightText() {
            if(copyRightText == null)
                copyRightText = getPreference(COPYRIGHT_URL);
            return copyRightText;
        }

        public void setCopyRightText(String copyRightText) {
            this.copyRightText = copyRightText;
            setPreference(COPYRIGHT_URL, copyRightText);
        }
    }
person Vivek Khandelwal    schedule 21.01.2013

Спасибо всем за все предложения. Теперь я использую только один экземпляр класса.

public class ApplicationDetails {

private static ApplicationDetails instance = null;

String supportURL;
String companyURL;
String copyRightText;

// with getter and setter methods 

public static ApplicationDetails getInstance() {
 if (instance == null) {
    instance = new ApplicationDetails();
 }
   return instance;
 }

}

И я устанавливаю и получаю вот так

 ApplicationDetails appDetails = ApplicationDetails.getInstance();
 appDetails.setSupportURL(supportURL);

и в деятельности

ApplicationDetails appDetails = ApplicationDetails.getInstance();
appDetails.getSupportURL();

Работает нормально.

person Mac    schedule 21.01.2013
comment
Это не всегда будет хорошим решением. Так как фреймворк андроида разработан таким образом, что он может убить ваше приложение, когда памяти меньше. В этом случае вы получите нуль для всех ваших полей, и вам придется снова установить строку. - person Vivek Khandelwal; 21.01.2013

Обновить

Когда вы устанавливаете значение на экране-заставке, этот объект в памяти был другим, а в другом действии вы создаете другой объект, который также отличается в памяти, поэтому вы получаете нуль.

Если это было вашим требованием, чтобы инициализировать URL-адрес на заставке и использовать его в другом, то есть много способов.

  1. Вы напрямую получаете строку в своей деятельности, когда попадаете на заставку.
  2. На заставке сделайте объект appDetails общедоступным статическим, чтобы вы могли получить доступ и к другим действиям.
  3. Реализуйте сериализацию в ApplicationDetails и поместите этот объект в putExtra, поскольку мы помещаем значение string, int и т. Д. Для передачи данных между действиями и получаем эти данные, используя пакет в запущенном действии.

Отредактировано

Для использования одного объекта вам нужно объявить этот объект общедоступным статическим на экране-заставке.

public static ApplicationDetails appDetails;

теперь присваивайте значение в заставке oncreate() и используйте его в другом действии или даже в другом классе также таким образом

public class AboutViewController extends Activity {

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

        // direct use object by class name
        System.out.println(" app support url " + SplashScreen.appDetails.getSupportURL());
    }

}
person Pratik    schedule 21.01.2013
comment
Что означает просто получение значения по объекту класса? И как здесь помогает инициализация значений пустыми (равно бесполезными) строками? - person Joachim Sauer; 21.01.2013
comment
хорошо, спасибо, я понял свою ошибку, как использовать только один объект для установки данных и получения их в разных активах? - person Mac; 21.01.2013