Подтвердить что ты не робот

Android: передача хэш-карты между действиями

У меня есть карта между строкой и объектом класса. Я заполняю эту карту в Activity1, и я хотел бы передать ее активности2.

public class NEW extends Activity {

    public class data {
            String name;
            float value;
                 ....   etc  }

 ......   
    static Map<String, data> data_map = new HashMap<String, data>();
   .....  }
4b9b3361

Ответ 1

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

[обновление]

Для всех downvotes загляните в Часто задаваемые вопросы о платформе Android: "Как передавать данные между Activity/Services в одном выражение?". Решение, которое я рекомендую, точно такое же, как...

Публичное статическое поле/метод

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

Да, есть предостережения для этого решения, но с ограниченной информацией, представленной OP, мы не можем предположить, что этот метод не будет работать.

Ответ 2

Лучший способ сделать это - вы можете выразить свои данные в примитивах, поддерживаемых Bundle, поэтому его можно поместить в намерение, которое вы отправляете с помощью методов Intent.putExtra(). (ЗА ИСКЛЮЧЕНИЕМ для использования Serializable, который чрезвычайно медленный и неэффективный.)

Однако вы не можете этого сделать, потому что (a) вы используете карту и (b) ваша карта содержит пользовательский тип данных.

Формально правильное решение этой точной проблемы состоит в том, чтобы написать собственный класс Parcellable, который заботится о сортировке/разборке вашей структуры данных. Я нарисую код здесь, хотя это может быть и не совсем правильно:

import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;

public class MyData implements Parcelable {
    HashMap<String, data> data_map = new HashMap<String, data>();

    public MyData() {
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int parcelableFlags) {
        final int N = data_map.size();
        dest.writeInt(N);
        if (N > 0) {
            for (Map.Entry<String, data> entry : data_map.entrySet()) {
                dest.writeString(entry.getKey());
                data dat = entry.getValue();
                dest.writeString(dat.name);
                dest.writeFloat(dat.value);
                // etc...
            }
        }
    }

    public static final Creator<MyData> CREATOR = new Creator<MyData>() {
        public MyData createFromParcel(Parcel source) {
            return new MyData(source);
        }
        public MyData[] newArray(int size) {
            return new MyData[size];
        }
    };

    private MyData(Parcel source) {
        final int N = source.readInt();
        for (int i=0; i<N; i++) {
            String key = source.readString();
            data dat = new data();
            dat.name = source.readString();
            dat.value = source.readFloat();
            // etc...
            data_map.put(key, dat);
        }
    }
}

Обратите внимание, что когда у вас есть настраиваемая структура данных, например, ваш класс данных, она может быть более чистой, чтобы также сделать эту Parcellable, поэтому она знает, как читать/писать ее содержимое на посылке, а код здесь просто вызовет .writeToParcel(...) и метод .readFromParcel(...), вместо того, чтобы знать подробности его содержимого. Таким образом, когда вы добавляете новые поля в "данные", вы не забываете также обновлять этот другой код маршаллинга, чтобы узнать о них.

Ответ 3

Я бы предложил использовать Intents, которые работают как для статических, так и для арбитальных объектов (если они реализуют Serializable). Создайте Intent для своего приложения, а затем передайте свой HashMap (а не карту, которая не реализует Serializable!) В качестве дополнительных данных

Intent act2 = new Intent(Activity2.SHOW_ME);
act2.putExtra("data", data_map);

Затем в Activity2 вы можете вызвать getIntent() и проверить через Intent.getAction().equals(Activity2.SHOW_ME), был ли вы тем, кто вызвал вашу активность. Если это так, вы можете получить доступ к своим дополнительным данным с помощью

Intent caller = getIntent();
if (caller.getAction().equals(Activity2.SHOW_ME)) {
   Map<String, NEW.data> data_map = (Map<String, NEW.data>)caller.getExtras().get("data");
}

Надеюсь, я все правильно набрал;) Это предполагает, что ваша строка действия Intent хранится как static final string SHOW_ME = "yourpackage.yourname"; в Activity2.

Если вам нужно уточнить, добавьте комментарий.

Ответ 4

Вы можете инкапсулировать свои данные в Bound Service, как описано в этом документе:

http://developer.android.com/guide/topics/fundamentals/bound-services.html

Не забудьте добавить свой сервер в файл манифеста.

Это решение имеет то преимущество, что вы отключите свои данные от вашего пользовательского интерфейса, что в конечном итоге приведет к более удобному дизайну.

Если возникнет такая необходимость, вы можете добавить оболочку обмена сообщениями в свой API-интерфейс службы, чтобы он мог быть вызван из других процессов/приложений

Ответ 5

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

Step1

public class GlobalClass extends android.app.Application 
{
 public static Map<String, NEW.data> data_map = new Map<String, NEW.data>();
}

Step2

После этого зарегистрируйте этот "GlobalClass" в AndroidManifest.xml

<application
    android:name=".GlobalClass"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
</application>

Step3

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

@Override
protected void onCreate(Bundle icicle)
{
 GlobalClass global = (GlobalClass)getApplication();
 Map<String, NEW.data> my_map_data = global.data_map;
}

Эти шаги могут быть полезны для вас...