2011-12-20 7 views
5

У меня есть база данных с одной строкой данных, которая будет использоваться во множестве действий. Мне нужно иметь доступ к идентификатору строки во всех действиях, чтобы я мог читать и записывать данные по различным активам с помощью моего адаптера базы данных. Я успешно использовал putExtra (Overthelimit.java) с намерением передать идентификатор строки для следующего действия. Затем переменной mRowId присваивается идентификатор строки, используя getExtra (Profile.java). Проблема, которую я сейчас имею, заключается в том, чтобы сделать mRowId доступным для других действий, то есть MyUsual и DrinksList, чтобы я мог обновлять данные по мере их поступления.сохранение значения переменной во всех действиях андроида

Вы можете видеть, что я попробовал putExtras, putSerializable, но не могу заставить его работать. Я думаю, что мне не хватает понимания.

Так что для моего профиля опции меню в деятельности ниже, я могу отправить значение курсора строки идентификатора профиля класса:

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 доступным для другого действия под названием DrinkList из MyUsual. так что у меня MyUsual ниже с кнопкой drink1 onClickListener, чтобы попытаться отправить идентификатор строки в 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.

ОК, спасибо. Поэтому ответьте на большие ответы, и я сделал это, но он падает, пытаясь получить данные. У меня есть это как мой класс Application:

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(); 

Мне все еще приходилось указывать длинное время при настройке и получении. Спасибо за все Ваши ответы.

ответ

12

Другой способ - создать класс приложения, доступный для всех видов деятельности. Чтобы сделать это, вы должны продлить вы Manifest с

<application 
    .. 
    android:name=".MyApplication" > 

и создать новый класс

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

внутри деятельности, вы можете получить доступ к RowId по

int mRowId = ((MyApplication) getApplicationContext()).rowId; 
+0

это здорово. поэтому у меня есть: public class OverthelimitApplication extends Application { private Long rowId; public Long getRowId() { return rowId; } public void setRowId (Длинное значение) { rowId = значение; }} с, чтобы установить: OverthelimitApplication app1 = (OverthelimitApplication) getApplicationContext(); app1.setRowId ((long) cursor.getColumnIndexOrThrow (OverLimitDbAdapter.KEY_ROWID)); и получить: mRowId = ((OverthelimitApplication) getApplicationContext()). GetRowId(); Но это не сработает. он падает. – user1095784

+0

что рушится? можете ли вы скопировать сообщение об ошибке из логарифма? – andreasg

+0

@andreasg Я знаю, что это 4 года спустя, но моя тоже рушится. Вот сообщение об ошибке: –

-1

Здесь вы хотите получить mRowId значение от всех видов деятельности, и это примитивных типов, поэтому

Либо использовать Shared Preferences для хранения данных или создать свой член поле как static globally, тогда вы можете использовать эти данные в вся жизнь цикл приложения ..

EDIT: также вы можете использовать Application class как синглтон для вашего приложения и создавать поля mRowId в этом классе, а также сделать метод геттер сеттер для этого поля ..

+0

Лично я не думаю, что «SharedPreference» идеально. Если OP хочет читать (или писать) при каждом действии, это операция с диском + синтаксический анализ каждый раз, когда вы хотите получить к нему доступ. – st0le

+0

хорошо, отлично. Попробуй это. Означает ли это, что если приложение было прервано, скажем, в приложении для телефона, данные будут потеряны, и мне нужно будет сбросить значение переменной? Благодарю. – user1095784

+1

NO. SharedPreferences сохраняются в хранилище, поэтому, даже если вы перезагрузите телефон или извлечете аккумулятор, или приложение будет прервано, значение будет сохранено до тех пор, пока вы его не измените. – Guillaume

6

Есть два варианта, которые я думаю, подходят для вашей цели:

  • SharedPreferences: дополнительное преимущество в том, что ваши переменные будут сохранены и доступны в следующий раз, когда вы запускаете приложение. Вы можете легко хранить примитивные типы в общих предпочтениях, например, ваш rowId.

  • Применение: вы можете subclass the application class, что-то вроде MyApplication extends Application, объявить в манифесте, что вы используете этот класс вместо приложения по умолчанию, и доступ к нему с помощью getApplication от всех видов деятельности. Дополнительным преимуществом является то, что вы можете хранить что угодно, даже сложную структуру данных в приложении, вы определяете элементы и методы доступа в своем классе MyApplication. Например, вы можете хранить всю строку данных в приложении, а не только rowId)

Лично я использую SharedPreferences помнить настройки, которые я хочу сохранить для пользователя, а не того, чтобы установить их снова каждый раз, когда приложение запускается, приятно. И я использую приложение для всех временных данных, которые я хочу проживать во всех действиях, пока приложение открыто.

1

Я Опишем два способа.

1) Используйте переменную static в любом из видов деятельности. Это быстрый, грязный и ленивый путь. Вас предупредили.

2) Создайте свой класс Application.

Создание простого класса MyApplication, который расширяет Application В Android Manifest, там должно быть поле для применения, убедитесь, что вы выбираете класс.

Типичный пример.

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! 
+0

Каковы недостатки использования статической переменной? Я говорю о вашем первом методе? –

+0

https://stackoverflow.com/questions/7026507/why-are-static-variables-considered-evil – st0le

0

Вы можете использовать ApplicationContext тоже.В манифесте, вы должны иметь что-то вроде этого:

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

Теперь вы можете получить доступ к Заявке от любой деятельности, благодаря:

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

Вы можете поместить свои атрибуты в этом классе, это будет доступна в любом месте вашего приложения. MyApp должен расширять приложение. См. Manifest и Application