Android - 在主要活动中保持变量的价值

时间:2014-03-11 22:43:42

标签: android variables android-activity

我想知道当我去另一个活动然后回到主要活动时,是否有任何解决方案可以将变量值保留在内存中(主要活动没有被杀死 - onCreate(Bundle) )参数为null)。在我的情况下,变量是ArrayList。

我通过将变量声明为静态来解决这个问题。此解决方案基于以下答案:https://stackoverflow.com/a/14604485/3195752

它有效,但我不喜欢它。每个类的实例都应该有自己的变量(list)。我知道我只有一个活动实例,但它似乎并不合适。

感谢您的回答!

编辑#1 atxe

添加一些代码

的AndroidManifest.xml

 <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.nuduoz.batchelorwork.uiprototype2" >
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:logo="@drawable/ic_action_floorplan_icon_green"
        android:theme="@style/Theme.Lightgreen" >
        <activity
            android:name="com.nuduoz.batchelorwork.uiprototype2.RoomArrange"
            android:label="@string/activity_room_arrange"
            android:theme="@style/Theme.Lightgreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.nuduoz.batchelorwork.uiprototype2.FloorPlan"
            android:label="@string/title_activity_floor_plan"
            android:parentActivityName="com.nuduoz.batchelorwork.uiprototype2.RoomArrange"
            android:theme="@style/Theme.Lightgreen">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="RoomArrange" />
        </activity>
    </application>

activity_room_arrange.xml

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="MergeRootFrame">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.nuduoz.batchelorwork.uiprototype2.RoomArrange"
        android:background="@android:color/white"
        />
    <!-- The left floor plan drawer -->
    <ListView android:id="@+id/left_drawer"
        android:layout_width="@dimen/left_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@color/d_green"
        android:dividerHeight="1dp"
        android:background="@color/action_bar_color"/>
    <!-- The right add equipment drawer -->
    <LinearLayout android:id="@+id/right_drawer"
        android:orientation="vertical"
        android:layout_width="@dimen/right_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:choiceMode="singleChoice"
        android:divider="@color/d_green"
        android:dividerHeight="1dp"
        android:background="@color/action_bar_color"/>

</android.support.v4.widget.DrawerLayout>

RoomArrange.java - 我试图删除所有不会影响活动变化的行

    public class RoomArrange extends ActionBarActivity {

    public final static String PLAN_NAME_MESSAGE = "com.nuduoz.batchelorwork.uiprototype2.PLAN_NAME_MESSAGE";
    private final static String PLAN_LIST_BUNDLE_ID = "com.nuduoz.batchelorwork.uiprototype2.PLAN_LIST_BUNDLE_ID";

    private static ArrayList<String> mFloorPlanList = new ArrayList<String>();
    private DrawerLayout mLeftDrawerLayout;
    private DrawerLayout mRightDrawerLayout;
    private ListView mLeftDrawerList;
    private LinearLayout mRightDrawerItems;

    private CharSequence mTitle;
    private ActionBarDrawerToggle mLeftDrawerToggle;
    private ActionBarDrawerToggle mRightDrawerToggle;
    private CharSequence mDrawerTitle;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_room_arrange);

        mTitle = mDrawerTitle = getTitle();

        // Fill list when its empty - application start
        if(mFloorPlanList.size() == 0)
        {
            List<String> tmpList = Arrays.asList(getResources().getStringArray(R.array.floorplans_array));
            mFloorPlanList.addAll(tmpList);
            mFloorPlanList.add(getResources().getString(R.string.drawer_add_new_plan));
        }

        mLeftDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        mLeftDrawerList = (ListView) findViewById(R.id.left_drawer);
        mRightDrawerItems = (LinearLayout) findViewById(R.id.right_drawer);

        // set up the drawer's list view with items and click listener
        mLeftDrawerList.setAdapter(new ArrayAdapter<String>(this,
                R.layout.drawer_list_item, mFloorPlanList));

        if (savedInstanceState == null)
        {
            //selectItem(0);
        }
        else
        {
            mFloorPlanList = savedInstanceState.getStringArrayList(PLAN_LIST_BUNDLE_ID);
            mLeftDrawerList.setAdapter(new ArrayAdapter<String>(this,
                            R.layout.drawer_list_item, mFloorPlanList));
        }

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (mLeftDrawerToggle.onOptionsItemSelected(item))
        {
            closeRightDrawer();
            return true;
        }

        switch (item.getItemId()) {
            // action with ID action_refresh was selected
            case R.id.action_arrange_add:
                onAddActionSelected();
                return true;

                //......

            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    // Click for swapping floor plans
    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView parent, View view, int position, long id) {
            selectItem(position);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle bundle)
    {
        bundle.putStringArrayList(PLAN_LIST_BUNDLE_ID, mFloorPlanList);
        bundle.putInt("a", 25);
        super.onSaveInstanceState(bundle);
    }

    /** Swaps floor plans, create new or edit */
    private void selectItem(int position) {
        // Create new floor plan
        if(position == mFloorPlanList.size() - 1)
        {
            // TODO Create new floor plan
            AlertDialog.Builder alert = new AlertDialog.Builder(this);

            alert.setTitle(getResources().getString(R.string.drawer_add_new_plan));
            alert.setMessage("Add name of a plan");

            // Set an EditText view to get user input
            final EditText input = new EditText(this);
            alert.setView(input);

            final RoomArrange activity = this;

            alert.setPositiveButton(getResources().getString(R.string.button_ok), new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    String value = input.getText().toString();

                    mFloorPlanList.add(mFloorPlanList.size() - 1, value);

                    // Call floor plan activity
                    Intent intent = new Intent(activity, FloorPlan.class);
                    intent.putExtra(PLAN_NAME_MESSAGE, value);
                    startActivity(intent);
                }
            });

            alert.setNegativeButton(getResources().getString(R.string.button_cancel), new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    // Canceled.
                }
            });

            alert.show();
        }
    }
}

activity_floor_plan.xml

<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.nuduoz.batchelorwork.uiprototype2.FloorPlan">

    <TextView
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

FloorPlan.java

public class FloorPlan extends ActionBarActivity {

        public final static String PLAN_NAME = "New floor plan";

        private String planName;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_floor_plan);

            Bundle extras;
            if (savedInstanceState == null) {
                extras = getIntent().getExtras();
                if(extras == null) {
                    planName= getResources().getString(R.string.plan_default_name);
                } else {
                    planName= extras.getString(RoomArrange.PLAN_NAME_MESSAGE);
                }
            } else {
                planName= (String) savedInstanceState.getSerializable(RoomArrange.PLAN_NAME_MESSAGE);
            }

            getActionBar().setTitle(planName);
        }


        @Override
        public boolean onCreateOptionsMenu(Menu menu) {

            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.floor_plan, menu);
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
            if (id == R.id.action_settings) {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }
    }

我真的不知道问题出在哪里.. :( ad:我知道我的代码可能会遇到一些问题,所以请随时指出它们。

2 个答案:

答案 0 :(得分:2)

如果您将变量声明为静态,则您没有保证在恢复该活动时变量值将保留在那里。如果内存不足,操作系统可能会终止您的活动。

如另一个答案中所述,将该信息保存到数据存储(文件系统,共享首选项,sqlite,...)是一种选择。但是,在我看来,这不是最干净的方式。我更喜欢重新创建Android文档建议的活动(及其状态):使用onSaveInstanceState()在娱乐时存储您想要的数据,然后在onCreate()(从包中)或{{1}中检索它}}

请查看此处的文档:http://developer.android.com/training/basics/activity-lifecycle/recreating.html

答案 1 :(得分:1)

使用内部数据存储数据。有关详细信息,请参阅此处:http://developer.android.com/guide/topics/data/data-storage.html#filesInternal

这种方法效果相对较好,并且在重新启动时仍然存在,但读取和写入都很痛苦。