java编程中有很多设计模式,其中最简单的应该就是单例模式了,相信做开发的朋友都知道单例模式,那么在Android开发中应该在何时使用单例模式呢?今天就来讨论这个问题,本人还是菜鸟,如果大家有什么意见,希望能不吝赐教。
假设有这样一个需求,我们在第一个Activity中有一个Person对象的一些基本信息,如姓名,年龄等,然后我们需要跳转到第二个Acitiviy中,在第二个Activity中可以编辑这些信息,当从第二个Activity中回来的时候,第一个Activity中的信息要求同步更新。
当然这个需求其实实现起来很简单,只需要在第一个Activity中调用onStartActivityForResult()方法来启动第二个Activity,当编辑好数据之后再调用onActivityResult()方法将数据返回就可以了,但是这么做的话有一个弊端,如果这个Person类的信息过多,在两个Activity中传递数据未免有些繁琐,这时候就可以通过单例模式来简单的实现这个需求。
首先创建一个Person实体类,把它定义为单例模式,另外,为了方便观看,这里还使用了Builder模式:
public class Person {
private String name;
private int age;
private boolean sex; //性别,true表示男,false表示女
private String address;
private static Person person = null;
private Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.sex = builder.sex;
this.address = builder.address;
}
/**懒汉式双重校验锁单例模式*/
private static Person getPerson(Builder builder) {
if (person == null) {
synchronized (Person.class) {
if (person == null) {
person = new Person(builder);
}
}
}
return person;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public static class Builder {
private String name;
private int age;
private boolean sex;
private String address;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder sex(boolean sex) {
this.sex = sex;
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
public Person builder() {
return getPerson(this);
}
}
}
然后是MainActivity的布局和类:
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="org.zack.singletontest.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="姓名:"
android:textSize="25dp"/>
<TextView
android:id="@+id/main_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="性别:"
android:textSize="25dp"/>
<TextView
android:id="@+id/main_sex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="年龄:"
android:textSize="25dp"/>
<TextView
android:id="@+id/main_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="地址:"
android:textSize="25dp"/>
<TextView
android:id="@+id/main_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp"/>
</LinearLayout>
<Button
android:id="@+id/main_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="编辑"
android:textSize="25dp"/>
</LinearLayout>
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private Button mainButton;
private TextView name, sex, age, address;
private Person person;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
person = new Person.Builder()
.name("张三")
.age(18)
.sex(true)
.address("北京")
.builder();
initView();
initData();
mainButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(EditActivity.newIntent(MainActivity.this, person));
}
});
}
@Override
protected void onResume() {
super.onResume();
initData();
}
/**初始化控件*/
private void initView() {
mainButton = (Button) findViewById(R.id.main_button);
name = (TextView) findViewById(R.id.main_name);
sex = (TextView) findViewById(R.id.main_sex);
age = (TextView) findViewById(R.id.main_age);
address = (TextView) findViewById(R.id.main_address);
}
/**初始化数据*/
private void initData() {
name.setText(person.getName());
sex.setText(boolean2sex(person.isSex()));
age.setText(String.valueOf(person.getAge()));
address.setText(person.getAddress());
}
/**将boolean类型的数据转换为性别*/
public static String boolean2sex(boolean b) {
if (b) {
return "男";
} else {
return "女";
}
}
}
以及EditActivity的布局和类:
activity_edit.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="org.zack.singletontest.EditActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="姓名:"
android:textSize="25dp"/>
<EditText
android:id="@+id/edit_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="性别:"
android:textSize="25dp"/>
<EditText
android:id="@+id/edit_sex"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="年龄:"
android:textSize="25dp"/>
<EditText
android:id="@+id/edit_age"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="地址:"
android:textSize="25dp"/>
<EditText
android:id="@+id/edit_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25dp"/>
</LinearLayout>
<Button
android:id="@+id/edit_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="完成"
android:textSize="25dp"/>
</LinearLayout>
EditActivity.java:
public class EditActivity extends AppCompatActivity {
private Button editButton;
private EditText name, sex, age, address;
// private static Person mPerson;
private Person person;
public static Intent newIntent(Context context, Person person) {
Intent intent = new Intent(context, EditActivity.class);
// mPerson = person; //直接通过Person对象来传递数据,避免了传递四个数据的繁琐
intent.putExtra("name", person.getName());
intent.putExtra("sex", person.isSex());
intent.putExtra("age", person.getAge());
intent.putExtra("address", person.getAddress());
return intent;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
initView();
initData();
}
private void initView() {
name = (EditText) findViewById(R.id.edit_name);
sex = (EditText) findViewById(R.id.edit_sex);
age = (EditText) findViewById(R.id.edit_age);
address = (EditText) findViewById(R.id.edit_address);
editButton = (Button) findViewById(R.id.edit_button);
editButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
person.setName(name.getText().toString());
person.setSex(sex2boolean(sex.getText().toString()));
person.setAge(Integer.valueOf(age.getText().toString()));
person.setAddress(address.getText().toString());
finish();
}
});
}
private void initData() {
Intent intent = getIntent();
person = new Person.Builder()
.name(intent.getStringExtra("name"))
.sex(intent.getBooleanExtra("sex", false))
.age(intent.getIntExtra("int", 0))
.address(intent.getStringExtra("address"))
.builder();
name.setText(person.getName());
sex.setText(MainActivity.boolean2sex(person.isSex()));
age.setText(String.valueOf(person.getAge()));
address.setText(person.getAddress());
}
private boolean sex2boolean(String sex) {
if (sex.equals("男")) {
return true;
} else if (sex.equals("女")) {
return false;
}
return false;
}
}
最后来运行试一下效果:
首先打开主页面:
然后点击编辑:
开始编辑:
编辑完成后点击完成:
可以发现,数据已更新