[原文] http://blog.petrnohejl.cz/handling-bundles-in-activities-and-fragments
Bundle是一个非常有用的数据容器,映射String值和各种可以Parceable的数据类型。所以,大体上Bundle是一个复杂的键值字典。Bundles用于在Intents/Activities/Fragments中进行传值。下面会讨论如何在Android中使用Bundles。
当你使用Intent创建Activity的时候,你可以传递一些额外的数据。数据存储在Bundle中,可以通过调用 getIntent().getExtras()方法来获取。有个好习惯是,为Activity实现一个newIntent()静态方法,这个方法返回一个用于创建这个Activity的Intent。通过这个方式,你可以在编译阶段检查传递给Activity的参数变量,同样,这个方式也是用于Service和Broadcast。
Bundle在Activity被重新初始化的时候同样会被使用到,用于保持当前示例的状态,比如在Activity的configuration发生变化的时候。你可以在onSaveInstanceState(Bundle) 方法的时候放入数据,在onCreate(Bundle)或者 onRestoreInstanceState(Bundle) 方法中来获取这些数据。这几个方法的主要区别是,onRestoreInstanceState(Bundle)方法会在onStart()方法之后被调用。
public class ExampleActivity extends Activity { public static final String EXTRA_PRODUCT_ID = "product_id"; public static final String EXTRA_PRODUCT_TITLE = "product_title"; private static final String SAVED_PAGER_POSITION = "pager_position"; public static Intent newIntent(Context context, String productId, String productTitle) { Intent intent = new Intent(context, ExampleActivity.class); // extras intent.putExtra(EXTRA_PRODUCT_ID, productId); intent.putExtra(EXTRA_PRODUCT_TITLE, productTitle); return intent; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_example); // restore saved state if(savedInstanceState != null) { handleSavedInstanceState(savedInstanceState); } // handle intent extras Bundle extras = getIntent().getExtras(); if(extras != null) { handleExtras(extras); } } @Override public void onSaveInstanceState(Bundle outState) { // save current instance state super.onSaveInstanceState(outState); // TODO } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { // restore saved state super.onRestoreInstanceState(savedInstanceState); if(savedInstanceState != null) { // TODO } } private void handleSavedInstanceState(Bundle savedInstanceState) { // TODO } private void handleExtras(Bundle extras) { // TODO } }
当创建一个新的Fragment实例时,可以通过 setArguments(Bundle) 方法传递参数。同时,可以通过getArguments()方法获取参数。有时候,让有很多参数的构造函数进行初始化工作,可能是不太合适的用法。Fragment实例有时可能会重新被创建,这样会导致数据的丢失,因为有额外参数的构造函数在Fragment重新初始化的时候并不会被调用,只有空构造函数被被调用。解决这个问题的最好方式通过实现静态构造方法 newInstance(), 这个方法里返回一个新的Fragment实例,并且通过setArguments方法来设置参数了Fragment的参数。
Fragment的状态可以通过 onSaveInstanceState(Bundle) 方法来进行保存。这个与Activity类似。数据可以通过 onCreate(Bundle), onCreateView(LayoutInflater, ViewGroup, Bundle), onActivityCreated(Bundle) 或 onViewStateRestored(Bundle)方法进行恢复。
Fragment 同样可以获取创建Activity示例时传入的Intent数据,可以通过getActivity().getIntent().getExtras()方法获取。
public class ExampleFragment extends Fragment { private static final String ARGUMENT_PRODUCT_ID = "product_id"; private static final String SAVED_LIST_POSITION = "list_position"; public static ExampleFragment newInstance(String productId) { ExampleFragment fragment = new ExampleFragment(); // arguments Bundle arguments = new Bundle(); arguments.putString(ARGUMENT_PRODUCT_ID, productId); fragment.setArguments(arguments); return fragment; } public ExampleFragment() {} @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // handle fragment arguments Bundle arguments = getArguments(); if(arguments != null) { handleArguments(arguments); } // restore saved state if(savedInstanceState != null) { handleSavedInstanceState(savedInstanceState); } // handle intent extras Bundle extras = getActivity().getIntent().getExtras(); if(extras != null) { handleExtras(extras); } } @Override public void onSaveInstanceState(Bundle outState) { // save current instance state super.onSaveInstanceState(outState); // TODO } private void handleArguments(Bundle arguments) { // TODO } private void handleSavedInstanceState(Bundle savedInstanceState) { // TODO } private void handleExtras(Bundle extras) { // TODO } }
You can find example code also on my GitHub in Android Templates and Utilities repo. This blogpost was inspired by Nick Butcher's post on Google Plus. Gotta some questions or ideas about Bundles? Follow me on Twitter or Google Plus.