Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Передача сложных объектов



В примере выше передавались простые данные - числа, строки. Но также мы можем передавать более сложные данные. В этом случае используется механизм сериализации.

Например, пусть у нас в проекте будет определен класс 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 используется ряд методов, каждый из которых предназначен для определенного типа данных. Основные методы:

  • writeString()
  • writeInt()
  • writeFloat()
  • writeDouble()
  • writeByte()
  • writeLong()
  • writeIntArray()
  • writeValue() (записывает объект типа Object)
  • writeParcelable() (записывает объект типа Parcelable)

Кроме того, объект 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; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.054 с.)
Главная | Случайная страница | Обратная связь