Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Передача сложных объектов
В примере выше передавались простые данные - числа, строки. Но также мы можем передавать более сложные данные. В этом случае используется механизм сериализации. Например, пусть у нас в проекте будет определен класс Product: package com.example.eugene.serializeapp; import java.io.Serializable; public class Product implements Serializable { private String name; private String company; private int price; public Product(String name, String company, int price){ this.name = name; this.company = company; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; }}Стоит отметить, что данный класс реализует интерфейс Serializable. Теперь изменим код MainActivity: package com.example.eugene.serializeapp; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void onClick(View v) { final EditText nameText = findViewById(R.id.name); final EditText companyText = findViewById(R.id.company); final EditText priceText = findViewById(R.id.price); String name = nameText.getText().toString(); String company = companyText.getText().toString(); int price = Integer.parseInt(priceText.getText().toString()); Product product = new Product(name, company, price); Intent intent = new Intent(this, SecondActivity.class); intent.putExtra(Product.class.getSimpleName(), product); startActivity(intent); }}Теперь вместо трех разрозненных данных передается один объект Product. В качестве ключа используется результат метода Product.class.getSimpleName(), который по сути возвращает название класса. И изменим класс SecondActivity: package com.example.eugene.serializeapp; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView textView = new TextView(this); textView.setTextSize(20); textView.setPadding(16, 16, 16, 16); Bundle arguments = getIntent().getExtras(); final Product product; if(arguments! =null){ product = (Product) arguments.getSerializable(Product.class.getSimpleName()); textView.setText(" Name: " + product.getName() + " \nCompany: " + product.getCompany() + " \nPrice: " + String.valueOf(product.getPrice())); } setContentView(textView); }}Для получения данных применяется метод getSerializable(), поскольку класс Product реализует интерфейс Serializable. Таким образом, мы можем передать один единственый объект вместо набора разрозненных данных. Parcelable Возможность сериализации объектов предоставляется напрямую инфраструктурой языка Java. Однако Android также предоставляет интерфейс Parcelable, который по сути также позволяет сериализовать объекты, как и Serializable, но является более оптимизированным для Android. И подобные объекты Parcelable также можно передавать между двумя activity или использовать каким-то иным образом. Например, в прошлой теме данные передавались между activity в виде объектов Product, которые использовали сериализацию. Теперь пусть класс Product применяет интерфейс Parcelable: package com.example.eugene.serializeapp;
import android.os.Parcel; import android.os.Parcelable;
public class Product implements Parcelable {
private String name; private String company; private int price;
public static final Creator< Product> CREATOR = new Creator< Product> () { @Override public Product createFromParcel(Parcel source) { String name = source.readString(); String company = source.readString(); int price = source.readInt(); return new Product(name, company, price); }
@Override public Product[] newArray(int size) { return new Product[size]; } };
public Product(String name, String company, int price){ this.name = name; this.company = company; this.price = price; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getCompany() { return company; }
public void setCompany(String company) { this.company = company; }
public int getPrice() { return price; }
public void setPrice(int price) { this.price = price; }
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeString(name); parcel.writeString(company); parcel.writeInt(price); } } Интерфейс android.os.Parcelable предполагает реализацию двух методов: describeContents() и writeToParcel(). Первый метод описывает контент и возвращает некторое числовое значение. Второй метод пишет в объект Parcel содержимое объекта Product. Для записи данных объекта в Parcel используется ряд методов, каждый из которых предназначен для определенного типа данных. Основные методы:
Кроме того, объект Parcelable должен содержать статическое поле CREATOR, которое представляет объект Creator< Product>. Причем этот объект реализует два метода. Они нужны для создания их ранее сериализованных данных исходных объектов типа Product. Так, метод newArray() создает массив объект Product. Метод createFromParcel создает из Parcel новый объект типа Product. То есть этот метод противоположен по действию методу writeToParcel. Для получения данных из Parcel применяются методы типа readString(), readInt(), readParcelable() и так далее - для чтения определенных типов данных. Причем важно, что данные в createFromParcel считываются из объекта Parcel именно в том порядке, в котором они добавляются в этот объект в методе writeToParcel. Допустим в activity, которая называется SecondActivity мы будем получать объект Product: package com.example.eugene.serializeapp;
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView;
public class SecondActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
TextView textView = new TextView(this); textView.setTextSize(20); textView.setPadding(16, 16, 16, 16);
Bundle arguments = getIntent().getExtras(); final Product product; if(arguments! =null){ product = arguments.getParcelable(Product.class.getSimpleName());
textView.setText(" Name: " + product.getName() + " \nCompany: " + product.getCompany() + " \nPrice: " + String.valueOf(product.getPrice())); } setContentView(textView); } } Для получения объекта Parcelable, переданного в activity, применяется метод getParcelable(). Причем никакого приведения типов не требуется. Для тестирования передачи Parcelable определим в файле activity_main.xml простейший интерфейс для MainActivity: <? xml version=" 1.0" encoding=" utf-8"? > < LinearLayout xmlns: android=" http: //schemas.android.com/apk/res/android" android: layout_width=" match_parent" android: layout_height=" match_parent" android: orientation=" vertical" android: padding=" 5dp" >
< TextView android: layout_width=" match_parent" android: layout_height=" 20dp" android: text=" Name: " /> < EditText android: id=" @+id/name" android: layout_width=" match_parent" android: layout_height=" 40dp" /> < TextView android: layout_width=" match_parent" android: layout_height=" 20dp" android: text=" Company: " /> < EditText android: id=" @+id/company" android: layout_width=" match_parent" android: layout_height=" 40dp" /> < TextView android: layout_width=" match_parent" android: layout_height=" 20dp" android: text=" Price: " /> < EditText android: id=" @+id/price" android: layout_width=" match_parent" android: layout_height=" 40dp" /> < Button android: id=" @+id/btn" android: layout_width=" wrap_content" android: layout_height=" wrap_content" android: onClick=" onClick" android: text=" Save" />
< /LinearLayout> А в коде MainActivity определим передачу данных в SecondActivity: package com.example.eugene.serializeapp;
import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
} public void onClick(View v) {
final EditText nameText = findViewById(R.id.name); final EditText companyText = findViewById(R.id.company); final EditText priceText = findViewById(R.id.price);
String name = nameText.getText().toString(); String company = companyText.getText().toString(); int price = Integer.parseInt(priceText.getText().toString());
Product product = new Product(name, company, price);
Intent intent = new Intent(this, SecondActivity.class); intent.putExtra(Product.class.getSimpleName(), product); startActivity(intent); } } |
Последнее изменение этой страницы: 2019-05-04; Просмотров: 260; Нарушение авторского права страницы