2011-12-20 61 views
5

Tôi có cơ sở dữ liệu với một hàng dữ liệu sẽ được sử dụng trên một số hoạt động. Tôi cần để có thể giữ id hàng có sẵn trong tất cả các hoạt động vì vậy tôi có thể đọc và ghi dữ liệu trên các hoạt động khác nhau với bộ điều hợp DB của tôi. Tôi đã sử dụng thành công putExtra (Overthelimit.java) thông qua mục đích chuyển một id hàng cho hoạt động tiếp theo. Biến mRowId sau đó được cung cấp id hàng bằng cách sử dụng getExtra (Profile.java). Vấn đề hiện tại của tôi là tạo mRowId cho các hoạt động khác, tức là MyUsual và DrinksList để tôi có thể cập nhật dữ liệu khi tôi đi.giữ giá trị biến trên tất cả các hoạt động trên android

Bạn có thể thấy tôi đã thử putExtras, putSerializable nhưng không thể làm cho nó hoạt động. Tôi nghĩ rằng tôi thiếu một số hiểu biết.

Vì vậy, cho tùy chọn trình đơn my profile trong hoạt động bên dưới tôi có thể gửi giá trị của id con trỏ hàng để hồ sơ lớp:

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

} 

Sau đó, làm cho nó có sẵn như là mRowId trong hoạt động thông tin của tôi dưới đây:

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; 
      } 

Sau đó, tôi cần phải đặt mRowId này thành hoạt động khác có tên là DrinkList từ MyUsual. vì vậy tôi có MyUsual dưới đây với một nút drink1 OnClickListener để thử và gửi id hàng để 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); 
     } 
} 

Từ DrinksList tôi chọn một thức uống và tôi cần phải sử dụng mRowId viết dữ liệu vào cơ sở dữ liệu thông qua 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; 


    } 

} 


} 

Xin lỗi vì bài đăng dài, nhưng tất cả những gì tôi cần làm là đặt giá trị này cho mRowId cho mọi hoạt động để tôi có thể đọc/ghi dữ liệu tại bất kỳ thời điểm nào. Các dữ liệu cũng cần phải có nếu ứng dụng bị tạm dừng hoặc bị gián đoạn bằng cách nói một cuộc gọi đến, vì vậy tôi sử dụng onSaveInstanceState.

ok, cảm ơn. Vì vậy, trả lời cho câu trả lời tuyệt vời và tôi đã làm điều này, nhưng nó treo cố gắng để có được dữ liệu. Tôi có điều này là lớp ứng dụng của tôi:

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

sau đó thiết lập giá trị với điều này:

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

sau đó cố gắng để có được giá trị với điều này và nó bị treo:

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

Tôi đã cố định nó ! sử dụng bộ này và nhận được:

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

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

Tôi vẫn phải xác định thời gian dài khi thiết lập và nhận. Cảm ơn tất cả đầu vào của bạn.

Trả lời

12

Một cách khác là tạo một lớp ứng dụng có sẵn cho tất cả các hoạt động. Để làm điều đó, bạn cần phải mở rộng bạn Manifest với

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

và tạo ra một lớp mới

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

bên trong hoạt động, bạn có thể truy cập ROWID bởi

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

thật tuyệt. vì vậy tôi có: lớp công khai OverthelimitỨng dụng mở rộng Ứng dụng { riêng tư Dài rowId; công khai Long getRowId() { hàng trả vềId; } void công khai setRowId (Giá trị dài) { rowId = value; } } với, để đặt: OverthelimitỨng dụng ứng dụng1 = (OverthelimitApplication) getApplicationContext(); app1.setRowId ((long) cursor.getColumnIndexOrThrow (OverLimitDbAdapter.KEY_ROWID)); và để nhận được: mRowId = ((OverthelimitApplication) getApplicationContext()). GetRowId(); Nhưng nó không hoạt động. Nó bị treo. – user1095784

+0

những gì đang gặp sự cố? bạn có thể sao chép thông báo lỗi từ logcat không? – andreasg

+0

@andreasg Tôi biết đây là 4 năm sau đó, nhưng tôi cũng bị rơi. Đây là thông báo lỗi: –

-1

Ở đây bạn muốn nhận được mRowId giá trị từ tất cả các hoạt động và nó là loại nguyên thủy, Vì vậy

Hoặc sử dụng Shared Preferences cho lưu trữ dữ liệu hoặc làm trường thành viên của bạn như một static globally, Sau đó, bạn có thể sử dụng dữ liệu này trong toàn bộ vòng đời ứng dụng ..

EDIT: Ngoài ra bạn có thể sử dụng Application class như một singleton cho các ứng dụng của bạn và tạo sân mRowId trong lớp này và cũng có thể làm cho phương thức getter setter cho lĩnh vực này ..

+0

Cá nhân, tôi không nghĩ 'SharedPreference' là lý tưởng. Nếu OP muốn đọc (hoặc viết) tại mỗi hoạt động, đó là một hoạt động đĩa + phân tích cú pháp mỗi khi bạn muốn truy cập nó. – st0le

+0

ok, tuyệt. Sẽ thử điều đó. Điều này có nghĩa là nếu ứng dụng bị gián đoạn bằng cách nói ứng dụng điện thoại, dữ liệu sẽ bị mất và tôi cần phải đặt lại giá trị biến? Cảm ơn. – user1095784

+1

KHÔNG. SharedPreferences được lưu vào bộ nhớ, vì vậy ngay cả khi bạn khởi động lại điện thoại hoặc tháo pin hoặc ứng dụng bị gián đoạn, giá trị sẽ được duy trì cho đến khi bạn thay đổi. – Guillaume

6

Có hai lựa chọn mà tôi nghĩ là phù hợp với mục đích của bạn:

  • SharedPreferences: lợi ích bổ sung là các biến của bạn sẽ giữ và sẵn lần sau khi bạn khởi động ứng dụng. Bạn có thể lưu trữ các loại nguyên thủy một cách dễ dàng trong các tùy chọn được chia sẻ, chẳng hạn như rowId.

  • Ứng dụng: bạn có thể subclass the application class, một cái gì đó giống như MyApplication extends Application, kê khai trong biểu hiện của bạn rằng bạn đang sử dụng lớp này thay vì các ứng dụng mặc định, và truy cập nó bằng cách sử getApplication từ tất cả các hoạt động của bạn. Lợi ích bổ sung là bạn có thể lưu trữ bất cứ điều gì, thậm chí một cấu trúc dữ liệu phức tạp trong ứng dụng, bạn xác định các thành viên và các phương thức truy cập trong lớp MyApplication của bạn. Ví dụ, bạn có thể lưu trữ toàn bộ hàng dữ liệu trong ứng dụng của bạn, không chỉ là rowId)

Cá nhân, tôi sử dụng SharedPreferences để nhớ các cài đặt mà tôi muốn được lưu lại cho người sử dụng, và không cần phải cài đặt chúng một lần nữa mỗi khi ứng dụng được khởi động là tốt đẹp. Và tôi sử dụng ứng dụng cho tất cả các dữ liệu tạm thời mà tôi muốn sống trên tất cả các hoạt động miễn là ứng dụng được mở.

1

tôi sẽ mô tả 2 cách.

1) Sử dụng biến số static trong bất kỳ hoạt động nào trong số các Hoạt động. Đây là cách nhanh chóng, bẩn thỉu và lười biếng. Mày đã được cảnh báo.

2) Tạo lớp học Application của bạn.

Tạo một lớp đơn giản MyApplication mở rộng Application Trong Tệp kê khai Android, phải có trường cho Ứng dụng, đảm bảo bạn chọn Lớp học của mình.

Ví dụ điển hình.

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; 
    } 
} 

Trong hoạt động của mình,

Gọi này

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

những nhược điểm của việc sử dụng biến tĩnh là gì? Tôi đang nói về phương pháp đầu tiên của bạn? –

+0

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

0

Bạn có thể sử dụng ApplicationContext quá.Trong Manifest của bạn, bạn nên có một cái gì đó như thế này:

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

Bây giờ, bạn có thể truy cập vào các ứng dụng từ bất kỳ Hoạt động nhờ vào:

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

Bạn có thể đặt thuộc tính của bạn trong lớp này, nó' sẽ có thể truy cập được ở mọi nơi trong ứng dụng của bạn. MyApp phải mở rộng Ứng dụng. Xem ManifestApplication

Các vấn đề liên quan