在所有Android活动中保持变量值

时间:2011-12-20 10:10:45

标签: android android-activity android-intent

我有一个数据库,其中包含一行数据,这些数据将用于多个活动。我需要能够在所有活动中保留行ID,以便我可以使用我的数据库适配器在不同的活动中读取和写入数据。我已成功使用putExtra(Overthelimit.java)通过意图将行id传递给下一个活动。然后使用getExtra(Profile.java)为mRowId变量赋予行id。我现在遇到的问题是让mRowId可用于其他活动,即MyUsual和DrinksList,这样我就可以随时更新数据。

你可以看到我尝试过putExtras,putSerializable但是无法让它工作。我想我错过了一些理解。

因此,对于我在下面的活动中的配置文件菜单选项,我可以将光标行id的值发送到Profile类:

 public class Overthelimit extends ListActivity {
private OverLimitDbAdapter dbHelper;
private Cursor cursor;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    this.getListView();
    dbHelper = new OverLimitDbAdapter(this);
    dbHelper.open();
    fillData();
    registerForContextMenu(getListView());
}


@Override
protected void onActivityResult(int requestCode, int resultCode,
        Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    fillData();

}
private void fillData() {
    cursor = dbHelper.fetchAllUserDrinks();
    startManagingCursor(cursor);
    //cursor.getCount();    

    String[] from = new String[] { OverLimitDbAdapter.KEY_USERNAME };
    int[] to = new int[] { R.id.label };

    // Now create an array adapter and set it to display using our row
    SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
            R.layout.user_row, cursor, from, to);
    setListAdapter(notes);
}



@Override
protected void onDestroy() {
    super.onDestroy();
    if (dbHelper != null) {
        dbHelper.close();
    }
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    return true;
} 

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
    case R.id.profile:
        Intent myIntent1 = new Intent(this, Profile.class);
        if(cursor.getCount() != 0) {
            //Toast.makeText(getApplicationContext(), "no profile",Toast.LENGTH_SHORT).show();
            myIntent1.putExtra(OverLimitDbAdapter.KEY_ROWID, cursor.getString(cursor.getColumnIndexOrThrow(OverLimitDbAdapter.KEY_ROWID)));
        }
        startActivityForResult(myIntent1, 0);
        return true;
    case R.id.myusual:
        Intent myIntent2 = new Intent(this, MyUsual.class);
        startActivityForResult(myIntent2, 0);
        return true;
    case R.id.trackme:
        Intent myIntent3 = new Intent(this, TrackMe.class);
        startActivityForResult(myIntent3, 0);
        return true;
    case R.id.moreinfo:
        Intent myIntent4 = new Intent(this, MoreInfo.class);
        startActivityForResult(myIntent4, 0);
        return true;


    }
    return super.onOptionsItemSelected(item);
}

}

然后在我的个人资料活动中将其作为mRowId提供:

mRowId = (bundle == null) ? null :
                (Long) bundle.getSerializable(OverLimitDbAdapter.KEY_ROWID);
             if (mRowId == null) {
                Bundle extras = getIntent().getExtras();
                mRowId = extras != null ? Long.parseLong(extras.getString(OverLimitDbAdapter.KEY_ROWID))
                                        : null;
            }

然后我需要将此mRowId用于MyUsual中另一个名为DrinkList的活动。所以我在下面的MyUsual上有一个按钮1 onClickListener来尝试将行ID发送到DrinksList:

public class MyUsual extends Activity {
private Long mRowId;
private OverLimitDbAdapter mDbHelper;
private Cursor cursor;
private TextView mDrink1Label;
private TextView mDrink1Units;

/** Called when the activity is first created. */
@Override
public void onCreate(final Bundle bundle) {
    super.onCreate(bundle);
    mDbHelper = new OverLimitDbAdapter(this);
    mDbHelper.open();
    setContentView(R.layout.my_usual);
    mDrink1Label = (TextView) findViewById(R.id.drink1Label);
    mDrink1Units = (TextView) findViewById(R.id.drink1Units);




    Button drink1 = (Button) findViewById(R.id.drink1Button);

    // get intent data i.e. which drink button pressed and mRowId                
          mRowId = (bundle == null) ? null :
            (Long) bundle.getSerializable(OverLimitDbAdapter.KEY_ROWID);
         if (mRowId == null) {
            Bundle extras = getIntent().getExtras();
            mRowId = extras != null ? Long.parseLong(extras.getString(OverLimitDbAdapter.KEY_ROWID))
                                    : null;
        }           

        //populateFields();

        drink1.setOnClickListener(new View.OnClickListener() {
         public void onClick(View view) {   
             setResult(RESULT_OK);
                //finish();
                Intent myIntent1 = new Intent(view.getContext(), DrinksList.class);
                myIntent1.putExtra("drinkButton", "drink1");

                if(cursor.getCount() != 0) {
                    myIntent1.putExtra(OverLimitDbAdapter.KEY_ROWID, cursor.getString(cursor.getColumnIndexOrThrow(OverLimitDbAdapter.KEY_ROWID)));
                }

             startActivityForResult(myIntent1, 0);
         }

        });




}

protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            //saveState();
            outState.putSerializable(OverLimitDbAdapter.KEY_ROWID, mRowId);
        }   
}

从DrinksList我选择一个饮料,我需要使用mRowId通过onListItemclick将数据写入数据库:

public class DrinksList extends ListActivity {
private ProgressDialog m_ProgressDialog = null; 
private ArrayList<CreateDrinkOption> m_drinks = null;
private DrinkAdapter m_adapter;
private Runnable viewDrinks;
private String drinkButton;
private Long mRowId;
private OverLimitDbAdapter mDbHelper;
private String databaseRow;
private Cursor cursor;

/** Called when the activity is first created. */

@Override
 public void onCreate(Bundle bundle) {
     super.onCreate(bundle);
     setContentView(R.layout.drinks_list);
     mDbHelper = new OverLimitDbAdapter(this);
     mDbHelper.open();
     m_drinks = new ArrayList<CreateDrinkOption>();
     this.m_adapter = new DrinkAdapter(this, R.layout.drink_row, m_drinks);
             setListAdapter(this.m_adapter);


     viewDrinks = new Runnable(){
         @Override
         public void run() {
             getDrinks();
         }
     };
 Thread thread =  new Thread(null, viewDrinks, "MagentoBackground");
     thread.start();
     m_ProgressDialog = ProgressDialog.show(DrinksList.this,    
           "Please wait...", "Retrieving data ...", true);



// get intent data i.e. which drink button pressed and mRowId                
     mRowId = (bundle == null) ? null :
        (Long) bundle.getSerializable(OverLimitDbAdapter.KEY_ROWID);
     if (mRowId == null) {
        Bundle extras = getIntent().getExtras();
        drinkButton = extras.getString(drinkButton);
        mRowId = extras != null ? Long.parseLong(extras.getString(OverLimitDbAdapter.KEY_ROWID))
                                : null;
    }


 }

protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    //saveState();
    outState.putSerializable(OverLimitDbAdapter.KEY_ROWID, mRowId);
}


 private Runnable returnRes = new Runnable() {

     @Override
      public void run() {
          if(m_drinks != null && m_drinks.size() > 0){
              m_adapter.notifyDataSetChanged();
              for(int i=0;i<m_drinks.size();i++)
              m_adapter.add(m_drinks.get(i));
          }
          m_ProgressDialog.dismiss();
          m_adapter.notifyDataSetChanged();
      }
    };

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id)
    {
    try
    {
    super.onListItemClick(l, v, position, id);
    CreateDrinkOption bkg = (CreateDrinkOption)l.getItemAtPosition(position);
    String drink1type = bkg.getDrinkType().toString();
    float drink1units = (bkg.getPercentageByVolume() * bkg.getVolume());
    //Toast.makeText(this, mRowId.toString(), Toast.LENGTH_LONG).show();

    mDbHelper.updateDrink(mRowId, drink1type, drink1units); 
    finish();

    }
    catch(Exception ex)
    {
    Toast.makeText(this, "error", Toast.LENGTH_LONG).show();
    }

   }



 private void getDrinks(){
     try{
         m_drinks = new ArrayList<CreateDrinkOption>();
         CreateDrinkOption o1 = new CreateDrinkOption();
         o1.setDrinkType("Beer - 1 pint");
         o1.setPercentageByVolume((float) 4.5);
         o1.setVolume((float) 0.5);
         m_drinks.add(o1);
         CreateDrinkOption o2 = new CreateDrinkOption();
         o2.setDrinkType("Wine - small glass");
         o2.setPercentageByVolume((float) 12);
         o2.setVolume((float) 0.125);
         m_drinks.add(o2);
         CreateDrinkOption o3 = new CreateDrinkOption();
         o3.setDrinkType("Spirit - single");
         o3.setPercentageByVolume((float) 40);
         o3.setVolume((float) 0.25);
         m_drinks.add(o3);
         CreateDrinkOption o4 = new CreateDrinkOption();
         o4.setDrinkType("Alcopop - bottle");
         o4.setPercentageByVolume((float) 5);
         o4.setVolume((float) 0.275);
         m_drinks.add(o4);
            Thread.sleep(1000);
         Log.i("ARRAY", ""+ m_drinks.size());
       } catch (Exception e) { 
        Log.e("BACKGROUND_PROC", e.getMessage());
       }
       runOnUiThread(returnRes);
   }   

 private class DrinkAdapter extends ArrayAdapter<CreateDrinkOption> {

     private ArrayList<CreateDrinkOption> items;

     public DrinkAdapter(Context context, int textViewResourceId, ArrayList<CreateDrinkOption> items) {
              super(context, textViewResourceId, items);
              this.items = items;
      }

     @Override
      public View getView(int position, View convertView, ViewGroup parent) {
              View v = convertView;
              if (v == null) {
                  LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                  v = vi.inflate(R.layout.drink_row, null);
              }
              CreateDrinkOption o = items.get(position);
              if (o != null) {
                      TextView tt = (TextView) v.findViewById(R.id.drinkdetail);
                      TextView bt = (TextView) v.findViewById(R.id.drinkunits);
                      if (tt != null) {
                            tt.setText("Type: "+o.getDrinkType());
                      }
                      if(bt != null){
                            bt.setText("Units: "+ String.valueOf(o.getPercentageByVolume() * o.getVolume()));
                      }
              }
              return v;


    }

 } 


}

很抱歉这篇文章很长,但我需要做的就是让mRowId的这个值可供所有活动使用,这样我就可以随时读/写数据了。如果应用程序通过拨打来电暂停或中断,数据也需要在那里,所以我使用onSaveInstanceState。

好的,谢谢。所以回复很好的答案,我已经完成了这个,但它崩溃试图获取数据。我有这个作为我的应用程序类:

public class OverthelimitApplication extends Application {
private Long rowId;
public Long getRowId() {
    return rowId;
}
public void setRowId(Long value) {
    rowId = value;
}
}

然后用这个设置值:

OverthelimitApplication app1 = (OverthelimitApplication)getApplicationContext();
    app1.setRowId((long) cursor.getColumnIndexOrThrow(OverLimitDbAdapter.KEY_ROWID));

然后试着用它来获取价值并崩溃:

mRowId = ((OverthelimitApplication) getApplicationContext()).getRowId(); 

我修好了!使用这个集合得到:

app1.setRowId(Long.parseLong(cursor.getString(cursor.getColumnIndexOrThrow(OverLimitDbAdapter.KEY_ROWID))));

mRowId = (long)((OverthelimitApplication)getApplicationContext()).getRowId(); 

在设置和获取时我仍然需要指定长时间。感谢您的所有意见。

5 个答案:

答案 0 :(得分:14)

另一种方法是创建一个可用于所有活动的应用程序类。 要做到这一点,你必须使用

扩展你的Manifest
 <application
    ..
    android:name=".MyApplication" >

并创建一个新类

public class MyApplication extends Application {
public int rowId = 0;
}

在活动中,您可以通过

访问rowId
int mRowId = ((MyApplication) getApplicationContext()).rowId;

答案 1 :(得分:7)

我认为有两种选择适合您的目的:

  • SharedPreferences额外的好处是,您的变量将在下次启动应用程序时保留并可用。您可以在共享首选项中轻松存储原始类型,例如rowId

  • 应用:您可以subclass the application class,例如MyApplication extends Application,在您的清单中声明您正在使用此类而不是默认应用程序,并访问它使用您所有活动中的getApplication。额外的好处是您可以在应用程序中存储任何内容,甚至是复杂的数据结构,您可以在MyApplication类中定义成员和访问方法。例如,您可以在应用程序中存储整行数据,而不仅仅是rowId

就个人而言,我使用SharedPreferences来记住我想为用户保存的设置,而不必在每次启动应用程序时再次设置它们。只要应用程序处于打开状态,我就会将应用程序用于所有活动中的所有临时数据。

答案 2 :(得分:2)

我将描述两种方式。

1)在任何一个活动中使用static变量。这是快速,肮脏和懒惰的方式。你已被警告过了。

2)创建Application课程。

创建一个扩展MyApplication的简单类Application 在Android Manifest中,应该有一个Application字段,请确保选择Class。

典型的例子。

public class MyApp extends Application
{
    private Object myGloballyAccessibleObject; //make getter and setter
    private static MyApp singleInstance = null;

    public static MyApp getInstance()
    {
        return singleInstance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        singleInstance = this;
    }
}

在您的活动中,

请致电

MyApp myApp = MyApp.getInstance();
myApp.getMyAwesomeObject(); //Booyaah!

答案 3 :(得分:0)

您也可以使用ApplicationContext。在你的Manifest中,你应该有这样的东西:

<application
    ...
    android:name="xx.xx.MyApp"
    ...>

现在,您可以通过以下方式从任何活动访问应用程序:

MyApp application = (MyApp)this.getApplicationContext();

您可以将属性放在此类中,它可以在应用中的任何位置访问。 MyApp必须扩展应用程序。见ManifestApplication

答案 4 :(得分:-1)

在这里,您希望从所有活动中获取mRowId值,它是原始类型,所以

使用Shared Preferences存储数据或将您的成员字段设为static globally,然后您可以在整个应用程序生命周期中使用此数据。

编辑:此外,您可以使用Application class作为应用程序的单例,并在此类中创建字段mRowId,并为此字段设置getter setter方法。