我有一个数据库,其中包含一行数据,这些数据将用于多个活动。我需要能够在所有活动中保留行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();
在设置和获取时我仍然需要指定长时间。感谢您的所有意见。
答案 0 :(得分:14)
另一种方法是创建一个可用于所有活动的应用程序类。 要做到这一点,你必须使用
扩展你的Manifest <application
..
android:name=".MyApplication" >
并创建一个新类
public class MyApplication extends Application {
public int rowId = 0;
}
在活动中,您可以通过
访问rowIdint 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必须扩展应用程序。见Manifest和 Application
答案 4 :(得分:-1)
在这里,您希望从所有活动中获取mRowId
值,它是原始类型,所以
使用Shared Preferences存储数据或将您的成员字段设为static globally
,然后您可以在整个应用程序生命周期中使用此数据。
编辑:此外,您可以使用Application class
作为应用程序的单例,并在此类中创建字段mRowId,并为此字段设置getter setter方法。