getParcelableArrayListExtra issue. Program crashing - android

I'm trying to pass an arraylist of objects to a new activity, I followed a tutorial and it looks as if I've done everything right but my program kept crashing. I've commented out the majority of the code to isolate the line that seems to be causing the crash and its the getParcelableArrayListExtra bit that seems to be the problem. Can anyone help?
New Activity:
public class DatabaseSearch extends ListActivity{
DBAdapter db = new DBAdapter(this);
ArrayList<String> listrecipes = new ArrayList<String>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.databasesearch);
Intent i = getIntent();
if (i != null) {
ArrayList<mydata> data = i.getParcelableArrayListExtra ("com.example.MyPantry.array");
}
}
}
Bit of code from the old activity--
I don't know if it matters but the new activity is being called within a dialog box
#Override
protected Dialog onCreateDialog(int id)
{
switch(id) {
case 0:
return new AlertDialog.Builder(this)
.setIcon(R.drawable.icon)
.setTitle("List all recipes that match over:")
.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
// TODO Auto-generated method stub
switch (item)
{
case 0:
percentageselected = 25;
break;
case 1:
percentageselected = 50;
break;
case 2:
percentageselected = 75;
break;
case 3:
percentageselected = 100;
break;
default:
break;
}
}
})
.setPositiveButton("OK", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton)
{
if (percentageselected == 0)
{
Toast.makeText(getBaseContext(), "Please make a selection", Toast.LENGTH_SHORT).show();
}
else
{
Intent intent = new Intent(getBaseContext(), DatabaseSearch.class);
intent.putParcelableArrayListExtra("com.example.MyPantry.array", array);
startActivity(intent);
}
}
})
.setNegativeButton("Cancel", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton)
{
dialog.dismiss();
}
})
.create();
}
return null;
}
My objects inside the array I want to pass--
public class mydata implements Parcelable {
private int recipeID;
private int ingredientID;
private String check = "unchecked";
private int percentage = 0;
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel data, int flags) {
// TODO Auto-generated method stub
data.writeInt(recipeID);
data.writeInt(ingredientID);
data.writeString(check);
data.writeInt(percentage);
}
//Other functions
}
Lastly I have this class that the tutorial instructed me to make...
public class MyCreator implements Parcelable.Creator<mydata> {
#Override
public mydata createFromParcel(Parcel source) {
// TODO Auto-generated method stub
return new mydata(source);
}
#Override
public mydata[] newArray(int arg0) {
// TODO Auto-generated method stub
return new mydata[arg0];
}
}
So I know it's quite a bit to look at but I'm just trying to be thorough. The problem starts to occur inside the if statement in the new activity.

When just passing data between intents, you can just mark your classes as Serializable (by implementing the Serializable marker interface) and add them directly to the intent as extras without having to do all this work with parcelable (parcelable is really only needed when binding to services).
It's hard to say why you're getting the error without seeing a stack trace or the constructor for mydata that populates the class using the Parcel.

Related

Return last element of listView and set it into text view - falls on NullPointerException

Please help me with little thing that make me crazy
I’m trying to set text in a textview that is the last element of a dynamic Array.
I add a function inside my Adapter that return the last element of the array.
I’m coming back to the Main Activity where I’d like to show the text and during time it falls at “nullpointerexception”.
Please help
Here is my code:
public class MainActivity extends Activity implements OnClickListener{
private static Context mContext;
public Button mExit, mHistory, mRating;
public TextView mSignal;
HistoryAdapt myLastItem;
List<HistoryItems> m_myLastItem;
#SuppressWarnings("unchecked")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivity.mContext=getApplicationContext();
mExit=(Button)findViewById(R.id.ExitButton);
mExit.setOnClickListener(this);
mHistory=(Button)findViewById(R.id.HistoryButton);
mHistory.setOnClickListener(this);
mRating=(Button)findViewById(R.id.RateButton);
mRating.setOnClickListener(this);
mSignal=(TextView)findViewById(R.id.SignalOfTheDayTV);
//### SET LAST ELEMENT INTO TEXTVIEW
m_myLastItem = new ArrayList<HistoryItems>();
myLastItem=new HistoryAdapt(mContext, m_myLastItem );
m_myLastItem= (List<HistoryItems>) myLastItem.getLastElement();
mSignal.setText(( (HistoryItems) m_myLastItem).getTitle());
// AppRater.app_launched(this);
// AppRater.showRateDialog(this, null);
//Get a Tracker (should auto-report)
((AppManager) getApplication()).getTracker(AppManager.TrackerName.APP_TRACKER);
}//oncreate
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static Context getAppContext(){
return MainActivity.mContext;
}
public void ExitState(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("You're about to quit Signals4Trading");
builder.setIcon(R.drawable.five);
//builder.setMessage("Your device has been registered successfully. You'll receive signals very soon.");
builder.setMessage("Are you sure you want to quit?");
builder.setCancelable(false);//can't click on the background of the activity
builder.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),"See you soon", Toast.LENGTH_LONG).show();
finish();
}//OnClickListener PositiveButton
});//anonymous class PositiveButton
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),"Enjoy your visit", Toast.LENGTH_LONG).show();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}//ExitState
public void goToHistoryActivity(){
Intent intent = new Intent(MainActivity.this, HistoryAct.class );
startActivity(intent);
}
public void rateApp(){
Intent intent = new Intent(MainActivity.this, Rate.class);
startActivity(intent);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()){
case R.id.ExitButton:
ExitState();
break;
case R.id.HistoryButton:
goToHistoryActivity();
break;
case R.id.RateButton:
rateApp();
break;
}
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
//Get an Analytics tracker to report app starts & uncaught exceptions etc.
GoogleAnalytics.getInstance(this).reportActivityStart(this);
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
//Stop the analytics tracking
GoogleAnalytics.getInstance(this).reportActivityStop(this);
}
}//MainActivity
**Adapter:**
package com.Signals4Trading.push.android;
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class HistoryAdapt extends BaseAdapter {
private final List<HistoryItems>items;
private final Context context;
public HistoryAdapt(Context context,List<HistoryItems>items){
this.context=context;
this.items=items;
}//constructor
#Override
public int getCount() {
// TODO Auto-generated method stub
return items.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return items.get(position);
}
#Override
public long getItemId(int id) {
// TODO Auto-generated method stub
return id;
}
//###FUNCTION THAT RETURN LAST ELEMENT
public HistoryItems getLastElement(){
HistoryItems lastItem = items.get(items.size());
if(items!=null && !items.isEmpty()){
lastItem = items.get(items.size()-1);
}
return lastItem;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(context, R.layout.historyitems, null);
holder = new ViewHolder();
holder.itemTitle = (TextView) convertView.findViewById(R.id.itemTitleTV);
holder.itemDate=(TextView) convertView.findViewById(R.id.itemDateTV);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.itemTitle.setText(items.get(position).getTitle());
holder.itemDate.setText(items.get(position).getDate());
return convertView;
}
class ViewHolder {
TextView itemTitle;
TextView itemDate;
}
}
//HistoryAdapt
you are getting this error because you have never intialized the object of your adapter class
HistoryAdapt in requires a context and and list to pass into it ,as defined in your constructor
This may be because Listitems is still referencing to null object. Have you called HistoryAdapt(context,items) constructor before calling
HistoryItems l_myLastItem= (HistoryItems) myLastItem.getLastElement(0);
?
Do as Haresh Chhelana said
public HistoryItems getLastElement(){
return items.get(items.size()-1);
}
the reason you are getting null pointer exception is because your list has not been initialized so it is referencing null. To get rid of this error you should first initialize your ArrayList then populate it as
//### SET LAST ELEMENT INTO TEXTVIEW
m_myListItem = new ArrayList();
//then add some data to arrayList for eg:
for (i=1;i<=10;i++){
m_myListItem.add(new HistoryItem().setTitle("title " + i));
}
myLastItem=new HistoryAdapt(mContext, m_myListItem ); //this should be m_myListItem not m_myLastItem
m_myLastItem= myLastItem.getLastElement();// m_myLastItem should be of type HistoryItem as HistoryItem m_myLastItem not List<HistoryItems> m_myLastItem
mSignal.setText(m_myLastItem.getTitle());
P.S. please have a look at your variable naming convention
No need to pass last item index instead directly get index from adapter list size.
public HistoryItems getLastElement(){
return items.get(items.size()-1);
}

Activity not destroying to release Heap in android?

I am trying to release heap size by destroying the current activity, while going to another activity.
I am using finish(); on backPreess()
But this is not releasing the heap.
on setContentView()
The heap size increases 16Mb. I want to release this increase in the heap after going to another activity. Can any one help how to do this?
My code is as following:
package com.stancil.levels;
public class PaintActivity extends ZebraActivity implements
PaintView.LifecycleListener, PaintView1.LifecycleListener1 {
private static final int REQUEST_PICK_COLOR = 1;
....
....
public PaintActivity() {
_state = new State();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Constants.context = getApplicationContext();
setContentView(R.layout.paint);
..................
...................
...............
}
public void onPreparedToLoad() {
// We need to invoke InitPaintView in a callback otherwise
// the visibility changes do not seem to be effective.
new Handler() {
#Override
public void handleMessage(Message m) {
new InitPaintView();
Log.v("PaintActivity", "After InitPaintView Called");
}
}.sendEmptyMessage(0);
}
private class InitPaintView implements Runnable {
private Bitmap _originalOutlineBitmap;
private Handler _handler;
public InitPaintView() {
// Make the progress bar visible and hide the view
_paintView.setVisibility(View.GONE);
_progressBar.setProgress(0);
_progressBar.setVisibility(View.VISIBLE);
_state._savedImageUri = null;
_state._loadInProgress = true;
_originalOutlineBitmap=_imageBitmap;
_handler = new Handler() {
#Override
public void handleMessage(Message m) {
switch (m.what) {
case Progress.MESSAGE_INCREMENT_PROGRESS:
// Update progress bar.
_progressBar.incrementProgressBy(m.arg1);
break;
case Progress.MESSAGE_DONE_OK:
case Progress.MESSAGE_DONE_ERROR:
// We are done, hide the progress bar
// the paint view back on.
_state._loadInProgress = false;
_paintView.setVisibility(View.VISIBLE);
_progressBar.setVisibility(View.GONE);
initiatePopupWindow();
break;
}
}
};
new Thread(this).start();
}
public void run() {
Log.v("Wasimmmmmmmmmmmmmmmm", "qqqqq 22");
_paintView.loadFromBitmap(_originalOutlineBitmap, _handler);
}
}
private static class State {
// Are we just loading a new outline?
public boolean _loadInProgress;
// The resource ID of the outline we are coloring.
//public int _loadedResourceId;
//
// If we have already saved a copy of the image, we store the URI here
// so that we can delete the previous version when saved again.
public Uri _savedImageUri;
}
#Override
public void onBackPressed() {
new AlertDialog.Builder(this)
.setTitle("Exit")
.setMessage("Do you want to go to Main Menu?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Constants.check_new=true;
Intent i=new Intent(PaintActivity.this,MainActivity.class);
// i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Do nothing.
}
}).show();
}
}
}
release yoru objects in onDestroy method, anyways, if there are no references to the detroyed activity, GC will automaticly clean up whenever its needed (it doesnt need to happen right after you closed your activity).
Alternatively theres a method to force running GC, but I wont even write about it cuz its not really a feature a typical application should use

Updating the list in the ListFragment (parent) with changes in DialogFragment AlertDialog

I have one ListFragment called MeasurementList which displays all registered measurement data. To register new measurement data Im using DialogFragment named NewMeasurement with custom made view in AlertDialog with required UI controls to be filled out.
Now, I need an elegant solution to update the measurement list in the ListFragment with the new registered measurement after the DialogFragment is dismissed. I don't want to update the list from the database, but rather just adding the newly created Measurement object to the list. I have tried to follow Android guidelines on how to make fragments communicate with activities through callback interfaces (Creating event callbacks to the activity). The MeasurementList passes its reference to the NewMeasurement so it can call it back after registering new measurement. The problem is how to save the listener reference in the Bundle in the NewMeasurement.newInstance() method. It mainly saved the primitive data types and not objects like in my case.
Any tip and suggestions would be appreciated.
MeasurementList.java
public class MeasurementList extends ListFragment implements OnMeasurementSetListener {
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addMeasurement:
NewMeasurement newMeasurementDialog = NewMeasurement.newInstance(this);
newMeasurementDialog.show(getFragmentManager(), "newMeasurementDialog");
break;
default:
break;
}
return true;
}
#Override
public void onMeasurementSet(Measurement measurement) {
MeasurementAdapter listAdapter = (MeasurementAdapter) getListAdapter();
listAdapter.add(measurement);
}
}
OnMeasurementSetListener.java
public interface OnMeasurementSetListener {
public abstract void onMeasurementSet(Measurement measurement);
}
NewMeasurement.java
public class NewMeasurement extends DialogFragment
{
private OnMeasurementSetListener mListener;
public static NewMeasurement newInstance(OnMeasurementSetListener listener)
{
NewMeasurement nm = new NewMeasurement();
Bundle b = new Bundle();
b.putSerializable("listener", listener); // NOT WORKING
f.setArguments(b);
return f;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View v = factory.inflate(R.layout.layout_dialog_new_measurement, null);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.title_alert_dialog_new_weight);
builder.setIconAttribute(R.drawable.add);
builder.setView(v);
builder.setPositiveButton(R.string.alert_dialog_ok, this);
builder.setNegativeButton(R.string.alert_dialog_cancel, this);
return builder.create();
if (savedInstanceState != null)
mListener = (OnMeasurementSetListener) savedInstanceState.getSerializable("listener");
}
}
Hi you can try to handle this onAttach method by setting new measurement it will create a call back to your activity.
public class MeasurementList extends ListFragment implements OnMeasurementSetListener {
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addMeasurement:
NewMeasurement newMeasurementDialog = NewMeasurement.newInstance(this);
newMeasurementDialog.show(getFragmentManager(), "newMeasurementDialog");
break;
default:
break;
}
return true;
}
#Override
public void onMeasurementSet(Measurement measurement) {
MeasurementAdapter listAdapter = (MeasurementAdapter) getListAdapter();
listAdapter.add(measurement);
}
}
NewMeasurement.java
public class NewMeasurement extends DialogFragment {
public interface OnMeasurementSetListener {
public abstract void onMeasurementSet(Measurement measurement);
}
private OnMeasurementSetListener onMeasurementSetListener;
private Measurement currentMeasurement;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
Measurement measurement = new Measurement();
measurement.s = "fragment";
onMeasurementSetListener = (OnMeasurementSetListener) activity;
setMeasurement(measurement);
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement onMeasurementSetListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Fragment Dialog");
builder.setIconAttribute(R.drawable.ic_launcher);
builder.setPositiveButton(R.string.app_name, new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
builder.setNegativeButton(R.string.app_name, new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
return builder.create();
}
private void setMeasurement(Measurement measurement) {
currentMeasurement = measurement;
onMeasurementSetListener.onMeasurementSet(measurement);
}
}
Sample Measurement.java
public class Measurement {
public String s;
}
Simply said, from your DialogFragment, you can call back to the Activity that contains your ListFragment, calling a newly created method, within the Activity that updates your ListFragment.

How to select itemclick event for listview with multiple rows in android?

I am trying to get values from server and retrieved response from server, the details responsed from server are need to be displayed in a listview, i achieved that too, but while onitemclick process only first row in list view performs the click action but it is not performing for the remaining rows, how can i achieve it, dat is whatever the row and item i'm selecting it has to be processed by my code, here is my code for the reference, .........
public void userInterface() throws JSONException
{
if(json_user.get(0) != null)
{
downloadList1 = (ListView)findViewById(R.id.lvinbox);
populateData();
downloadList1.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
// TODO Auto-generated method stub
fma=(TextView)findViewById(R.id.src);
st=(TextView)findViewById(R.id.sub);
fma.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
// TODO Auto-generated method stub
String fm=fma.getText().toString();
String s=st.getText().toString();
Intent m = new Intent(getApplicationContext(), InActivity.class);
m.putExtra("f", fm);
m.putExtra("s", s);
startActivity(m);
}
});
st.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
// TODO Auto-generated method stub
String fm=fma.getText().toString();
String s=st.getText().toString();
Intent m = new Intent(getApplicationContext(), InActivity.class);
m.putExtra("f", fm);
m.putExtra("s", s);
startActivity(m);
}
});
}
});
}
else
{
Toast.makeText(getApplicationContext(),"Empty", Toast.LENGTH_LONG).show();
finish();
Intent menu = new Intent(getApplicationContext(), MenActivity.class);
menu.putExtra("username", dest);
startActivity(menu);
}
}
public void populateData() throws JSONException
{
resultVector = new Vector<ListDataItemInbox>();
int len = json_user.length();
System.out.println("length--------------------->"+len);
for(int i=0;i<len;i++)
{
JSONObject obj=json_user.getJSONObject(i);
listData = new ListDataItemInbox();
listData.sets(obj.getString(KEY_S));
listData.setd(obj.getString(KEY_D));
resultVector.add(listData);
myHandler.post(myRunnable);
}
}
private Handler myHandler = new Handler();
private Runnable myRunnable = new Runnable()
{
public void run()
{
customListAdapter = new ListViewAdapterInbox(InActivity.this);
customListAdapter.setResultsData(resultVector);
downloadList1.setAdapter(customListAdapter);
}
};
You can do something like this.
make the ArrayList in list adapter class
ArrayList<Integer> selectedIds = new ArrayList<Integer>();
and create this method also in that same class.
public void toggleSelected(Integer position){
selectedIds.clear();
selectedIds.add(position);
}
Now whenever you click on any item of listview pass that item position to this method. And inside your getView method set the check before setting the text. something like this..
if (selectedIds.contains(position)){
----- your code ----
}else{
----- your code ----
}
it perform the operation only on selected position . Try it.!

What if you don't want to create dozen classes for AlertDialogs?

I have many different states according to which I need to feedback to User with a message in form of AlertDialog. It's just insane to create a separate class for each alert. What I have now is:
class FeedbackAlertDialog extends DialogFragment {
private String message;
private int action;
FeedbackAlertDialog() {
}
FeedbackAlertDialog(String message, int action) {
this.message = message;
this.action = action;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setCancelable(false)
.setTitle(message)
.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
switch (action) {
case action: // It's impossible because the int should be final
}
startActivity(new Intent(getActivity(), MainActivity.class));
}
}).show();
}
}
The problem is that I can't use switch because int should be final. How to come up with this situation?
use:
FeedbackAlertDialog.this.action
As far as i can see this should be in the switch.
This same way is used for accesing higher level variables (Notice Setters in a simple model).
in your case you have to first get into the scope of the root object(your case FeedbackAlertDialog).
It was just impossible because you need to use a constant in switch.
EDIT ::
Try this simple java demo at your computer system:
public class CalcDemo {
public static void main(String[] args) {
int n1 = 6, n2 = 3;
int opr = 1;
MyMath math = new MyMath(n1, n2, opr);
System.out.println("Answer :: "+math.getResult());
}
}
class MyMath {
int n1, n2, opr;
public MyMath() { }
public MyMath(int n1, int n2, int opr) {
this.n1 = n1;
this.n2 = n2;
this.opr = opr;
}
public int getResult() {
//int ch = opr;
switch (opr) {
case 1: return n1-n2;
//break;
case 2: return n1+n2;
default : System.out.println("Invalid Choice");
break;
}
return 0;
}
}
Do one Trick as following:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setCancelable(false)
.setTitle(message)
.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
final int action1 = action; // <---- --- Try This
switch (action1) { // <--- --- Use as This
case action1: // I THINK, NOW THIS IS POSSIBLE
}
startActivity(new Intent(getActivity(), MainActivity.class));
}
}).show();
}

Categories

Resources