2011-12-20 17 views
5

Tengo una base de datos con una fila de datos que se utilizará en una serie de actividades. Necesito poder mantener la Id. De fila disponible en todas las actividades para que pueda leer y escribir datos en diferentes actividades con mi adaptador de base de datos. He utilizado con éxito putExtra (Overthelimit.java) con la intención de pasar una identificación de fila a la siguiente actividad. La variable mRowId recibe la identificación de la fila usando getExtra (Profile.java). El problema que ahora tengo es hacer que mRowId esté disponible para otras actividades, como MyUsual y DrinksList, así puedo actualizar los datos a medida que avanzo.manteniendo un valor variable en todas las actividades de Android

Puede ver He intentado putExtras, putSerializable pero no puedo hacer que funcione. Creo que me falta algo de comprensión.

Así que para mi opción del menú perfil en la actividad puedo enviar el valor de la fila Identificación del cursor perfil de clase:

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

} 

A continuación, ponerlo a disposición como mRowId en mi actividad siguiente perfil:

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

Necesito hacer que este mRowId esté disponible para otra actividad llamada DrinkList de MyUsual. así que tengo MyUsual a continuación con un botón drink1 OnClickListener para tratar de enviar el identificador de fila para 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); 
     } 
} 

De DrinksList selecciono una copa y tengo que usar el mRowId escribir los datos en la base de datos a través de la 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; 


    } 

} 


} 

lo siento por el largo post, pero todo lo que tiene que hacer es hacer que este valor para mRowId a disposición de todas las actividades para que pueda leer/escribir datos en cualquier momento. Los datos también deben estar allí si la aplicación está detenida o intervenida por, por ejemplo, una llamada entrante, entonces uso onSaveInstanceState.

bien, gracias. Así que responda a las mejores respuestas y lo he hecho, pero se bloquea al tratar de obtener los datos. Tengo esto como mi clase de aplicación:

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

valor a continuación, establecer con esto:

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

luego tratar de obtener el valor con esto y se bloquea:

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

he arreglado ! usando esto el conjunto y obtienes:

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

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

Todavía tuve que especificar mucho tiempo al establecer y obtener. Gracias por todas sus aportaciones.

Respuesta

12

Otra forma es crear una clase de aplicación que esté disponible para todas las actividades. Para hacer eso, usted tiene que extender a manifestar con

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

y crear una nueva clase

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

dentro de las actividades, se puede acceder al rowid por

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

eso es genial. entonces tengo: public class OverthelimitApplication extends Application { private Long rowId; public Long getRowId() { return rowId; } public void setRowId (Valor largo) { rowId = value; } } con, para establecer: OverthelimitApplication app1 = (OverthelimitApplication) getApplicationContext(); app1.setRowId ((long) cursor.getColumnIndexOrThrow (OverLimitDbAdapter.KEY_ROWID)); y obtener: mRowId = ((OverthelimitApplication) getApplicationContext()). GetRowId(); Pero no funciona. se cuelga – user1095784

+0

¿Qué es estrellarse? ¿Puedes copiar el mensaje de error del logcat? – andreasg

+0

@andreasg Sé que esto es 4 años más tarde, pero el mío también se está cayendo. Aquí está el mensaje de error: –

-1

Aquí usted desea conseguir mRowId valores de toda actividad y es tipos primitivos, Así

O bien utilizar Shared Preferences para almacenar datos o hacer que su campo de miembro como static globally, A continuación, puede utilizar estos datos en su todo el ciclo de vida de aplicaciones ..

EDIT: también puede utilizar Application class como un producto único para su aplicación y crear un campo mRowId en esta clase y también hacer método getter setter para este campo ..

+0

Personalmente, no creo que 'SharedPreference' sea ideal. Si el OP quiere leer (o escribir) en cada actividad, eso es una operación de disco + un análisis cada vez que desea acceder a él. – st0le

+0

bien, genial. Intentaremos eso. ¿Esto significa que si la aplicación fue interrumpida por, digamos, la aplicación del teléfono, se perderían los datos y tendría que restablecer el valor de la variable? Gracias. – user1095784

+1

NO. Las preferencias compartidas se guardan en el almacenamiento, por lo tanto, incluso si reinicia el teléfono o extrae la batería, o la aplicación se interrumpe, el valor se mantendrá hasta que lo modifique. – Guillaume

6

Hay dos opciones que creo que son aptos para su propósito:

  • SharedPreferences: la ventaja añadida es que las variables se mantienen y disponible la próxima vez que inicie la aplicación. Puede almacenar tipos primitivos fácilmente en preferencias compartidas, como su rowId.

  • Aplicación: puede subclass the application class, algo así como MyApplication extends Application, declarar en su manifiesta que está utilizando esta clase en lugar de la aplicación por defecto, y acceder a ella usando getApplication de todas sus actividades. El beneficio adicional es que puede almacenar cualquier cosa, incluso una estructura de datos compleja en la aplicación, usted define el miembro y los métodos de acceso en su clase MyApplication. Por ejemplo, podría almacenar toda la fila de datos en la aplicación, no sólo el rowId)

Personalmente, yo uso SharedPreferences a recordar la configuración que yo quiero ser salvo para el usuario, y no tener que ajustarlas nuevamente cada vez que se inicia la aplicación es agradable. Y utilizo la aplicación para todos los datos temporales que quiero vivir en todas las actividades, siempre que la aplicación esté abierta.

1

I' Describiré 2 maneras.

1) Use una variable static en cualquiera de las actividades. Esta es la manera rápida, sucia y perezosa. Has sido advertido.

2) Cree su clase Application.

crear una clase simple MyApplication que se extiende Application En el manifiesto de Android, debe haber un campo de aplicación, asegúrese de elegir su clase.

Ejemplo típico.

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

En sus actividades,

Llame a este

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

¿Cuáles son las desventajas de usar una variable estática? Estoy hablando de tu primer método? –

+0

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

0

Puede utilizar el Application Context también.En su manifiesto, debe tener algo como esto:

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

Ahora, puede acceder a la aplicación desde cualquier actividad gracias a:

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

Usted puede poner sus atributos en esta clase, es Serás accesible desde cualquier lugar de tu aplicación. MyApp debe extender la aplicación. Ver Manifest y Application

Cuestiones relacionadas