I have 2 Activities : First activity user clicks on a button which launches the 2nd activity. The 2nd Activity does all the work.
I launch the 2nd Activity as follows which is inside a onClickListener Inner Class and I have tried explicitly calling it with (FirstActivity.this,Simple.Class) but same thing happens.
Intent test = new Intent(arg0.getContext(),Simple.class);
startActivity(test);
On the emulator, I see the screen move over like its calling the 2nd activity but all I get is a black screen but nothing is loaded from my layout. I looked at logcat and I do see some binder thread failed messages. This is the onCreate function from my 2nd activity but I do not get any results from either the screen or logcat showing me that the Log functions were called:
public void onCreate(Bundle savedState)
{
Log.d("SimpleActivity","OnCreate Started");
super.onCreate(savedState);
setContentView(R.layout.simple);
Log.d("SimpleActivity","OnCreate Ended");
}
Note : I have called the base constructor in OnCreate() with super.onCreate(savedState) in my code above.
What happened to me was I was overriding the wrong onCreate method. I was overriding public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) when I really needed to override protected void onCreate(#Nullable Bundle savedInstanceState). Maybe this might help someone!
It's possible that onCreate doesn't get called, if the activity has never been destroyed,
if for some reason an activity hangs around, next time its instantiated it is not recreated but resumed instead...
At least that's what im Dealing with right now in my code... Life cycle of Activities seem a good logical explanation.. However 99% of time I do rely on onCreate being called when startingActivity and it doesn't fail me....
Edit: And of course its because I wasn't calling finish() when exiting the activity. Doh.
This is not related to this certain issue, but also this can happen when activity is not declared in manifest file)
Be careful that if your method belongs to AppCompatActivity or Activity .
It is up to what you implemented to your Class
If you want to add lifecycle or any override methods, I recommend you to press
CTRL+O or do Code > Override methodsand there you can see where the method belongs
remove android:launchMode="singleTask" from manifest
you should #Override onCreate and add super.onCreate() in it
#Override
public void onCreate(Bundle savedState)
{
super.onCreate(savedState);
Log.d("SimpleActivity","OnCreate Started");
setContentView(R.layout.simple);
Log.d("SimpleActivity","OnCreate Ended");
}
my case
(1) mainActivity -> (2) open Adaptor - startActivity -> (3) mainActivity onCreate() doesn't get to triggered.
I resolved this by adding finish();. in mainActivity.
follow the below steps to check your application.
1.did you override the right method? if not overriding the below method, this method will be triggered, when you startActivity.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
2.Make sure that you registered the activity in manifest.xml
2.1 is your activity has android:launchMode="singleInstance" ?
(if your application doesn't need to be singleinstance, consider to remove.
but my case I need singleinstance. hence i moved to the next step)
use finish()
public void openSearch(View view) {
Intent intent = new Intent(this, BookInfoActivity.class);
intent.putExtra(...);
startActivity(intent);
finish(); // add like this.}
why do we need to use "finish()"?
Screen A -> click button on A -> Screen B -> click button on B -> screen A with some new data that you get from Screen B
if you don't call finish() method(in A button) , that means the A is still in your background
even you are seeing the screen B.
hence, when you trigger startActivity on screen B, it just simply shows the running A screen.
however if you use finish() method (in A button), when you go to B Screen,
it destroys the A screen, so when you go back to A screen by clicking B method( 'StartActivity') it creates A screen and trigger onCreate() Method .
You need to call the super.onCreate(savedState) method. Take a look at Activity doc.
public void onCreate(Bundle savedState)
{
super.onCreate(savedState);
}
Related
I have seen a lot of questions and answers about recreating the current activity after changing the application's Night Mode, but I have seen nothing on how to refresh the back stack Activities.
Say I have the backstack A > B > C. Activity C allows to change the night mode by calling AppCompatDelegate.setDefaultNightMode(). After this call, the current Activity (C), can refresh its theme with delegate.applyDayNight() or recreate().
However, when the user navigates back to B or A, the activities are still using the "old" mode, either day or night.
I tried to add something like that to the Activities:
override fun onResume() {
super.onResume()
delegate.applyDayNight()
}
But it does not seem to work.
I did multiple attempts to fix this:
One idea would be to recreate the backstack completely like suggested here or here, but since the backstack is not static, it's not doable for me.
Another idea would be to have a class that handles the night mode change and provides a LiveData. Each Activity would listen to the LiveData for a mode change and call recreate(). However, we are stuck in an infinite loop because the Activity would recreate directly after starting to listen to the LiveData.
I find it hard to believe that I am the first one trying to refresh the Activities from the backstack after changing the night mode. What did I miss?
Thanks!
If you can detect when the day/night mode has changed, you can simply recreate an activity that is resumed when the back stack is popped.
In the following demo, there are three activities: A, B and C. A creates B and B creates C. Activity C can change the day/night mode. When C is popped, activity B sees the change in the day/night mode and calls reCreate() to recreate the activity. The same happens in activity A when activity B is popped.
The video below shows the effect. The light-colored background is the "day" mode and the dark is "night" mode.
I have created a GitHub project for this demo app. If this works as a solution, I can incorporate more text into the answer from the project.
Refreshing your back stack completely is probably overkill and may add some overhead/lag to the UX; and as you mentioned, most applications will not have access to a full, static back stack.
You are essentially describing a more general issue: global changes to the theme or WindowManager itself affect the subsequent drawing of views. But previous layouts for Activities in the stack may not be redrawn. It might seem odd for you in this situation, but there could also be many good reasons why one would not want to redraw an Activity in the stack if once the user goes back to it. And so this is not an automatic feature.
I can think of a couple of options:
1) Write a custom class inheriting from Activity that invalidates all it's views when it moves to the front of the stack again. E.g. in onResume() or onRestart(), call (if in Fragment)
View view = getActivity().findViewById(R.id.viewid);
view.invalidate();
Use this custom Activity for all your activities that you want to keep consistent with the current day/night mode.
2) Use ActivityLifecycleCallbacks. This helps keep all your logic in one place, and avoids the need for custom inheritance as above. You could invalidate your views here as needed as activities are paused/resumed. You could include a Listener, if it is your app that is changing the theme, and record as SharedPreference, for example.
To use, add the callbacks to your Application class:
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
#Override
public void
onActivityCreated(Activity activity, Bundle savedInstanceState) {
//can check type of Activity for custom behaviour, if using inheritance
if(activity instanceof MainActivity) {
mMainActivities.put(activity, new MainActivityEntry((MainActivity)activity));
//...
}
}
#Override
public void
onActivityDestroyed(Activity activity) {
}
#Override
public void
onActivityPaused(Activity activity) {
}
#Override
public void
onActivityResumed(Activity activity) {
if(activity instanceof MainActivity) {
//...
}
//can update Entry properties too
final MainActivityEntry activityEntry = mMainActivities.get(activity);
if(activityEntry != null) {
//record state /perform action
}
}
#Override
public void
onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void
onActivityStarted(Activity activity) {
}
#Override
public void
onActivityStopped(Activity activity) {
}
});
Quick answer:
#Override
protected void onRestart() {
super.onRestart();
recreate();
}
You add the above codes to your MainActivity and it will work.
create a static boolean variable in the project and in each activity check if the boolean is true or false, then apply daylight and night based on value.
I just want to Clear all the data of Previous Activity. Means when i will go back to previous activity it need to call all the asyncatsk again as a fresh new activity.
Because when i was goes in a next activity i was doing some changes in data sequence but i will come back i need to call agin asynctask for original data
So anyone have idea about it ??
and yes i just want to clarify that Below's Function is not working
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
There are a couple options depending on your situation.
First, you could try clearing your savedInstanceState like this:
public void onCreate(Bundle savedInstanceState){
super.onCreate(null);
}
Or like this:
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.clear();
}
Second, if you're hoping to have this specifically on the "backpressed" event,
you could override onBackPressed to create a new instance of your activity, rather than the default of returning to the activity with its saved state.
#Override
public void onBackPressed(){
//super.onBackPressed(); // EXCLUDE this line
Intent intent = new Intent(this,TheNextActivity.class);
startActivity(intent);
}
#iguarna 's answer is also something to try, it all depends on the situation and what you're hoping to accomplish
If you want to re-initialize your activity in any way when you come back to it, just reset the values you want in onResume().
If that is not what you were looking for, please clarify your question.
im creating redirect to some view on object method. this method doesn't use the parent view.
it works but when i click back navigation it doesn't showing the previous page (previous page is object oncreate() method itself), it return to the top parent activity. here is my code :
Object method on create :
public class FormDatabase extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.form_database);
method member of object method :
public void showArrayResult(View view)
{
setContentView(R.layout.profile_listview);
how can when i click back navigation i would return to previous object onCreate() method NOT the parent method (MAIN_ACTIVITY).
Hope my description is clear enough. Thanks.
To switch between different views in the same activity, and still maintain the ability to use the back stack (back button), you should probably use Fragments.
If the two views are completely independent then you should consider moving it into its own separate Activity.
You can override the onBackPressed() callback method to interrupt killing the activity and instead SetContentView as you did in onCreate()
EDIT
But Nic is right about moving to a fragment or another activity.
A component such as an activity should manage one task. Otherwise it is considered as bad practice.
Im really new to android and i have a little problem that i dont know how to solve.
Im having a small application that prints out the Activity lifes circles methods like this:
protected void onCreate(){
super.onStart()
print("onStart was called"); //this is a void and its only printing a text
}
protected void onStart(){
super.onStart()
print("onStart was called");
}
and so on...
While im i portrait mode the app is showing all the methods on the screen but when i switch to landscape the activity object is of course destroyed and it creates the first three methods again.
Im using onSaveInstanceState an onRestoeeInstaceState to try to save printed order on the screen while i switch from portrait to landscape.
How can i make it work?
example of app output in portrait mode:
onCreate was called
onStart was called
onResume was called
onPause was called
onStop was called
onRestart was called
onStart was called
onResume was called
i want theese prints to stay even if i switch to landscape.
This is onSaveInstanceState and onRestoreInstanceState i dont really know how to solve the problem here.
#Override
protected void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
}
If you go to the manifest I believe you are able to edit it to allow portrait and landscape displays and also have it recall the savedInstanceState. Sorry I can't give you a more detailed answer at the moment.
I'm looking for a single answer (but I might be asking the wrong question)
Question- does any event only get called once TOTAL until an activity is destroyed?
I ask because when my user rotates the phone to landscape oncreate and onstart are both invoked causing a reload of sorts.
I'm looking for an event that I could put behavior into that would only get run 1x (until the activity is killed)
Thank you in advance
If it is specific to the Activity just check your savedInstanceState parameter in the onCreate event. If it is null, run your code, if not, your code has already been run.
Example:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if(savedInstanceState == null) {
// Run your code
}
}
savedInstanceState will always be null when onCreate is run for the first time, and it will be populated thereafter.
You don't really specify what you're trying to do with it, so I can't guarantee this is appropriate for your use, but Application.onCreate is only called once.
If you want to eliminate the recreation of your activity on an orientationchange you can listen for configchanges in the manifest.
<activity
android:name=".MyActivity"
android:configChanges="orientation" >
</activity>
And then you can override onConfigurationChanged like so:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged( newConfig );
LinearLayout main = (LinearLayout) findViewById( R.id.mainLayout );
main.requestLayout();
}
to recreate the layout so that it matches the new orientation, without recreating the entire activity.
Check http://developer.android.com/guide/topics/resources/runtime-changes.html to handle configuration changes and to maintain your huge data between them...if all you need to maintain between the configuration change is just the settings,you can use the onSavedInstanceState() and onRestoreInstanceState() callbacks and the given bundles.