I have an activity that allows the user to start a second activity. The second activity has a list of items which I add to an array list. When I return to the previous activity I want to display the size of the array list.
However I am having a problem with onResume(). It is called when my first activity is created and as a result generates an error as the array list does not exist when it is first launched!
onResume():
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
getIntentData();
calcSubTotal(orderData);
}
getIntentData():
public void getIntentData(){
b = new Bundle();
b = getIntent().getExtras();
orderData = b.getParcelable("order");
Toast.makeText(this.getApplicationContext(), orderData.size(), Toast.LENGTH_LONG).show();
}
onCreate() of second activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_starters);
createTestData();
b = new Bundle();
orderData = new MenuItemList();
adapter = new MenuItemArrayAdapter(this, starters);
this.setListAdapter(adapter);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Toast.makeText(this.getApplicationContext(), l.getItemAtPosition(position).toString() + " clicked", Toast.LENGTH_LONG).show();
//add clicked item to orderData....
MenuItem m = (MenuItem)l.getItemAtPosition(position);
//create new item
orderData.add(m);
}
Any idea how I might be able to control this?
ERROR:
java.lang.RuntimeException: Unable to resume activity {com.example.waitronproto3/com.example.waitronproto3.SectionsActivity}: java.lang.NullPointerException
I think you may want to have a look at startActivityForResult instead, when you're starting your second Activity. It'll allow your second activity to return a result back to your first activity. You can read up on it at the Activity documentation, specifically the "Starting Activities and Getting Results" section of the document.
Edit: By the looks of your code - nothing you're doing is either storing a bundle from the second activity and sending it back to the first. So you'll never get the proper Bundle data in your first activity. As suggested, look into startActivityForResult to launch your second activity with. This will allow you to return data back into your first activity with ease.
However I am having a problem with onResume(). It is called when my first activity is created and as a result generates an error as the array list does not exist when it is first launched!
I recommend changing getIntentData() to check if the appropriate data exists first:
public void getIntentData(){
Intent intent = getIntent();
if(intent != null && intent.hasExtra("order")) {
orderData = b.getParcelable("order");
Toast.makeText(this.getApplicationContext(), orderData.size(), Toast.LENGTH_LONG).show();
calculateSubTotal(order);
}
}
And update onResume():
#Override
protected void onResume() {
super.onResume();
getIntentData();
}
(Though you could simply put getIntentData() in onResume() now.)
Your onResume() will be called after onCreate() according to the Android Lifecycle so you will want to check that the data is not null before trying to use it.
`if(intentData != null)
//do something`
Related
I am new to android and learning things with fragments and have made a demo for it,in that i am having a fragment from which we can go to another activity at there some calculation is performing and after that we come back to frgament at that time i want to dislay that calculation value to my fragment's textview,So which life cycle method should i use to do so?i already used onresume which is not working...
public void onResume () {
super.onResume();
//tvFollowings.setText((sharedConnect.getCurrentUser().userFollowingCount)
// + " Following");
System.out.print("------user count is-------" + String.valueOf(sharedConnect.getCurrentUser().userFollowingCount));
Toast.makeText(getActivity(), "------user count is-------" + String.valueOf(sharedConnect.getCurrentUser().userFollowingCount), Toast.LENGTH_SHORT).show();
}
Yout have to use startActivityForResult(...) when calling your activity, then you can get any information you need in your fragments onActivityResult().
The best approach which works, toggle between onPause and onResume. No need to even bother the parent activity
private boolean allowRefresh = false;
#Override
public void onResume() {
super.onResume();
//Initialize();
if(allowRefresh){
allowRefresh=false;
//call your initialization code here
}
}
#Override
public void onPause() {
super.onPause();
if (!allowRefresh)
allowRefresh = true;
}
onResume will always be called when your fragment gets loaded, so initial state of allowRefresh should be false so the fragment does not get loaded twice
Once you open new activity whilst the fragment is active, onPause is called, here set allowRefresh to true only if allowRefresh is false.
When the fragment regains focus, check if allowRefresh is true and redo your initialization. A good code practice is put all your initialization code in one function.
You can use Bundle to do the same in Android
Create the intent:
Intent i = new Intent(this, ActivityTwo.class);
AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
String getrec=textView.getText().toString();
//Create the bundle
Bundle bundle = new Bundle();
//Add your data to bundle
bundle.putString(“stuff”, getrec);
//Add the bundle to the intent
i.putExtras(bundle);
//Fire that second activity
startActivity(i);
Now in your second activity retrieve your data from the bundle:
//Get the bundle
Bundle bundle = getIntent().getExtras();
//Extract the data…
String stuff = bundle.getString(“stuff”);
You can refer here for more.POST
You can use the onResume() method of the Fragment
public class Fragment_ABC extends Fragment {
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_abc, container, false);
return view;
}
#Override
public void onResume() {
super.onResume();
// PERFORM YOUR OPERATION OVER HERE
}
}
Let me know if this works for you ! :)
In your fragment write below code and overide onActivityResult(int requestCode, int resultCode, Intent data) method
Intent intent = new Intent(getApplicationContext(),TrendingQuestions.class);
intent.putExtra("categoryId", Integer.parseInt(categoryId));
startActivityForResult(intent, 101);
In your next activity after you got the result just set result
Intent result = new Intent();
setResult(Activity.RESULT_OK, result);
finish();
If onActivityResult is not getting called please check this link
Then do one thing .. use the Activities onResume Method in which you are showing the Fragment and then from within this Activity's OnResume call the Fragment' Function where you want to refresh the Fragment.
For example.
You have a Activity_A in which you have defined the fragment, let it be Fragemtn_A. Now you are navigating to Activity_B from within this Fragment_A.
Now when you are leaving Activity_B, then the onResume() method of the Activity_A will be called for sure, and from the onResume() of Activity_A you can call the function of Fragment_A and perform your operations that you want.
For calling any fragment's function from withing the Activity you can follow this link :
Calling a Fragment method from a parent Activity
Let me know if this works for you! :)
I have a form. Here, the user fills in details like event name, description, location etc. To select the location, I have set a button. This is my button code:
btnMap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent map = new Intent(getApplicationContext(), Map2.class);
startActivity(map);
}
});
I select the location from there, and the data is passed back to my main intent correctly. But the thing is, the data in the other fields like event, description etc. that users filled in are lost.
I tried startActivityForResult(map,1); too. Doesn't work. Is there a way to keep the data, without sending them in a bundle to the other intent and getting them back? like the select image button does? It goes to the gallery and comes back without resetting the other fields
contactImageImgView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Image"), 1);
}
});
You need to save your activity state.
Override the method onSaveInstanceState and persist all your data in the bundle
In onCreate, if savedInstanceState is not null, restore all your data and set all the fields.
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("MY_FIELD", 43);
// ... other fields
super.onSaveInstanceState(savedInstanceState);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
if (savedInstanceState != null) {
int value = savedInstanceState.getInt("MY_FIELD");
// ... update your views
} else {
// no previous state, start fresh
}
}
Details here
Note: you have mentioned that rotation is blocked. This is generally bad for the user unless it's part of the feature of the app.
Explanation:
A screen rotation is a configuration change that causes the activity to restart with the appropriate resources. There are many more configuration changes such as screen unlock,device docked etc. Not all of them trigger an activity restart but some do. When your activity restarts due to a configuration change, onSaveInstanceState gets called and savedInstanceState will be not-null when onCreate is called.
When you start a new activity Android may destroy the previous one to recover some of the resources it was consuming. In that case, when you return to that previous activity, it is actually a new instance of the Activity subclass and the internal state has been lost. It's up to you to save and restore any state necessary within the onSaveInstanceState and onCreate callback methods, respectively.
Have a look at this page for more information and examples: Recreating an Activity | Android Developers
public class FormActivity extends Activity {
private static final String NAME = "NAME";
private EditText nameEdit;
// Declare other view references here...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_form);
nameEdit = (EditText) findViewById(R.id.name_edit);
// Find other views...
if (savedInstanceState != null) {
final String nameValue = savedInstanceState.getString(NAME, "");
nameEdit.setText(nameValue);
// Restore other saved values...
} else {
// No saved values to restore
}
}
#Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
final String nameValue = nameEdit.getText().toString()
outState.putString(NAME, nameValue);
// Put (save) other values into the outState bundle...
super.onSaveInstanceState(outState, outPersistentState);
}
// Other FormActivity code...
}
I am learning Android. I am creating an application that have 2 activities: List Activity list all records from a local SQLite and Edit activity will create/update record.
On Edit activity, I have a button. When the button clicked, I will process creating/updating the record then returning back to parent activity (List activity).
On Button click. I have 2 solutions to process Create/Update:
1. Process Create/Update in UI thread ( Not using AsyncTask )
This solution is fine but I may have to show 'Processing' dialog.
2. Use AsyncTask -- so creating/updating happens in background Thread. Here is my code in Edit Activity:
---- NOTE that Edit activity use Fragment so getActivity() method will return the instance of EditActivity
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AsyncTask<Phrase, Integer, Integer> asyncTask = new AsyncTask<Phrase, Integer, Integer>() {
#Override
protected Integer doInBackground(Phrase... params) {
Phrase phrase = params[0];
if (phrase._id > 0) {
PhraseDao.update(DbManager.openWrite(getActivity()), phrase);
} else {
PhraseDao.insert(DbManager.openWrite(getActivity()), phrase);
}
return null;
}
#Override
protected void onPostExecute(Integer result) {
Intent intent = new Intent();
getActivity().setResult(Activity.RESULT_OK, intent);
// Close Edit Activity then Go back to List activity
getActivity().finish();
// MY QUESTION: What happens if the EditActivity (getActivity) already destroyed?
// How can I handle destroyed activity here
}
};
asyncTask.execute(a_phrase);
}
});
I don't know how to handle 'onPostExecute' method in the case Edit Activity ( accessed by getActivity()) Already destroyed.
Anyone have any ideas? Thank you!
Add a null check to see if activity exists i.e
if(getActivity() != null){
Intent intent = new Intent();
getActivity().setResult(Activity.RESULT_OK, intent);
getActivity().finish();
}
The main activity of the application is to display a list. The user clicks on something on the list which opens a edit screen. Upon fisnish, the edit screen is closed - and I want the original list to be updated with whatever hapenned on the edit screen. I save the data to a file - and I can just read it again to update the list. However I don't know where to insert the re-read code.
In the ListActivity - what method is called whe the list gets focus again?
This is my main List activity code:
Creating the view:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Inflate our UI from its XML layout description.
setContentView(R.layout.my_activity);
list=new Data_List(this); // my data reading class
list.read_data(); // reads from a file
load_dynamic_list();
}
Loading the data:
private void load_dynamic_list(){
ladapter=new
list_adapter(this,android.R.layout.simple_list_item_1,list); // the type is actually ignored // getview function in list_adapter handles everything
setListAdapter(ladapter);
this.getListView().invalidate();
}
Something was selected:
protected void onListItemClick (ListView l, View v, int position, long id){
int a;
intent = new Intent(this,Editing.class);
intent.putExtra("New_entry",0);
intent.putExtra("Entry",position);
//start the second Activity
this.startActivity(intent);
}
In the Editing function I end off like this:
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v.getId() == R.id.button_save){
do_save(); // saves to a file
// I want something like: caller.getListView().invalidate();
finish();
}
if(v.getId() == R.id.button_cancel){
finish();
}
}
What method can I override or call that will execute when the editing is done? At that point I want to read_data() and then load_dynamic_list() again.
You have to use AsyncTask.
Prefer URL :
http://steveliles.github.com/android_s_asynctask.html
http://www.vogella.com/articles/AndroidPerformance/article.html
With example :
http://labs.makemachine.net/2010/05/android-asynctask-example/
#Override
protected void onResume() {
super.onResume();
list=new Data_List(this);
list.read_data();
load_dynamic_list(); // becuase whatever was edited needs to be reread.
}
I have the following code in one activity:
in= new Intent(ThisActivity.this,AnotherActivity.class);
imgarr = new ImageView[55];
imgarr[0]=(ImageView) findViewById(R.id.species3);
imgarr[0].setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
b.putString("specno",Integer.toString(0)); in.putExtras(b);
in.setClassName("com.DuckHuntersJournal","com.DuckHuntersJournal._1_TagKillActivity");
startActivity(in);
}
});
And this code in another:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu1tagkill);
if ((savedInstanceState != null) && savedInstanceState.containsKey("specno")) {
Log.e(tag, "intent from species not null");
species.setText(savedInstanceState.getString("specno"));
}
However, savedInstanceState is null.
Why am I not getting any data back from the first activity?
You need to use :
getIntent().getExtras().getString("specno");
in order to get the passed string from the first activity.
EDIT: I'm not sure what you are trying to do... for getting data from another Activity that started the current one you need to use getIntent().getExtras().
For saving your current stat when the Activity goes to background you save the data in the onSaveInstanceState() method and then in the onCreate(Bundle savedInstance) method you get the saved data from the savedInstance parameter.
You'll need to do the following in your receiving Activity:
String species = getIntent().getStringExtra("specno");