передать имя класса через контекст и использовать его для хранения статического значения в другом классе - PullRequest
0 голосов
/ 17 июня 2011

Диалог и массив отображаются очень хорошо, я просто хочу иметь возможность установить статическую переменную из исходного класса в onClick, который находится в методе, который находится в другом классе. Все из try, catch и <?> были вещи, которые я вставил по настоянию компилятора:

public class Setter
    {
    public void myList(Context context, Class<?> thisclass, int arrayid, String choice)
        {
        return new AlertDialog.Builder(context)
        .setItems(arrayid, new OnClickListener()
            {
            @Override
            public void onClick(DialogInterface dialog, int which)
                {
                setChoice(thisclass, context, arrayid, which, choice);
                }
            })
        .create();
        }           
    public void setChoice(Class<?> thisclass, Context context, int arrayid, int which, String choice)
        {
        String[] array = context.getResources().getStringArray(arrayid);
        try
            {
            Field f = thisclass.getDeclaredField(choice);
            f.set(null, array[which]);
            }
        catch (SecurityException e)
            {
            e.printStackTrace();
            }
        catch (NoSuchFieldException e)
            {
            e.printStackTrace();
            }
        catch (IllegalArgumentException e)
            {
            e.printStackTrace();
            }
        catch (IllegalAccessException e)
            {
            e.printStackTrace();
            }
        }
    }

public class ClassA extends Activity
    {
    static String stringa;
    Setter setted = new Setter();
    ...
    public void onCreate()
        {
        super.onCreate();
        ...
        AlertDialog thinga = setted.myList(this, getclass(), R.array.thinga, stringa).show();
        ...
        }
    }

Когда я выбираю элемент из списка, я получаю это от отладчика:

ClassCache.findFieldByName(Field[], String) line: 438   
Class.getDeclaredField(String) line: 666    
Setter.setChoice(Class, Context, int, int, String) line: 45 // the line with the Field

Я думаю, что я пропускаю класс неправильно, но это немного не соответствует моей нынешней глубине.

У меня есть несколько разных классов, каждый со своими static String с. Я передаю метод под именем Stringchoice) и context того, на что я надеялся, был оригинальный класс, который вызвал метод, который вызвал метод, который привел к приведенному ниже коду. Я надеялся, что смогу позвонить по номеру context.choice = something, и аппарат прочитает это как ClassA.stringa = something; как мне это сделать?

Вкратце, я хочу иметь список элементов, из которых пользователь может выбрать содержимое диалога, и чтобы их выбор был сохранен и доступен для класса, который вызвал создание диалога. Возможно, я все делаю неправильно, но мне надоело иметь дело с другими «клуджами», связанными с использованием блесен для того же.

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

Ответы [ 3 ]

1 голос
/ 17 июня 2011

В Java нет замыканий, но вы можете приблизиться к анонимным внутренним классам.

String output;
public void onCreate() {
    Setter.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            output  = "selected";
        }
    });
}

См. Также этот учебник свинга: http://download.oracle.com/javase/tutorial/uiswing/events/actionlistener.html

Edit: В духе вашего примера это должно выглядеть так:

public class Setter
{
public void setChoice(IsetString setter, String something)
    {
    setter.setString(something);
    }
}


class ClassA extends Activity implements setString
{
static String stringa;
string polka = "dots";
Setter setted = new Setter();
...
public void onCreate()
    {
    super.onCreate();
    ...
    setted.setChoice(new IsetString() {

        @Override
        public void setString(String s) {
            stringa = s;
        }
    }, polka);
    ...
    }
}

interface IsetString {
    void setString(String s);
}
1 голос
/ 17 июня 2011

Краткий ответ - используйте API Reflection .

Длинный ответ - вам необходимо получить доступ к Fields нужного контекстаClass.Получив доступ к экземплярам поля, вы можете установить их значения с помощью метода set () ;вызов API немного сложен, так как вам нужно передать ссылку на объект (объект контекста, а не класс контекста), поле которого вы хотите изменить.

Необходимо, чтобы ваш Context, choice и something параметры метода, содержат необходимую информацию, чтобы сделать эту операцию максимально простой.Другими словами, класс Context может содержать фактический объект Class (или способ его получения), который содержит поле.

0 голосов
/ 17 июня 2011

Вы можете использовать отражение для этого. Предположим, что ваш контекст - это сам класс

public void setChoice(Class<?> context, String choice, String something)
{
   try {
     Field f = context.getDeclaredField(choice);
     f.set(null, something);
   } catch (....) {
   }
}

Добавить правильную обработку исключений


Обратите внимание, что первый аргумент set является нулевым. Это верно только для статических методов. Поэтому вы можете проверить, что этот метод является статическим, используя f.getModifiers().

...