I am trying to pass an object to an activity through Intent, and as I'm debugging, I noticed that apparently I never even get into the onCreate() method of the activity. Even though the activity starts, I have the layout and everything, I don't get a chance to debug, because the breakpoint inside the onCreate() method is never reached. How is this possible, what am I not understanding here? Help :)
listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
String selection = itemsArray[groupPosition][childPosition];
Class calc = null;
switch (selection) {
case "Calc1":
calc = Calc1.class;
break;
case "Calc2":
calc = Calc2.class;
break;
}
Intent intent = new Intent(Main.this, calc);
intent.putExtra("controller", getController());
startActivity(intent);
return false;
}
});
The activity is started on a OnChildClick event, the object I'm trying to pass is the controller (returned by getController() method)
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.calc1);
controller = (Controller) getIntent().getSerializableExtra("controller");
setController(controller);
editA = (EditText) findViewById(R.id.editA);
editB = (EditText) findViewById(R.id.editB);
}
This is the onCreate(), I set the breakpoint at setContentView(), and like I said, apparently I never get there... I feel like I'm missing something here.
Btw. I'm brand new to android ;)
Thanks for reading!
The Android activity lifecycle can be a bit tricky at first. Here's a diagram that explains it fairly well: https://github.com/xxv/android-lifecycle and you can get a lot more detail on all the activities here: https://developer.android.com/reference/android/app/Activity.html#onCreate(android.os.Bundle)
It's possible that the activity goes straight to onResume or onRestart, but if you want to find out for sure (and this is a great way to learn more about the activity lifecycle!) put some logs in a bunch of the different activity methods (onCreate, onPause, onRestart, etc...). Then try things like navigating between the different activities, killing the app, pressing the home button, locking your screen, rotating the screen, etc. You'll notice that the flow is not exactly the same, and it will help you figure out where to put your code in your particular use case. Hope this helps!
When set break point, did you run in Debug Mode ?
To run in debug mode
try menu Run > Debug 'app' (Alt + Shift + D)
To run in release mode
try menu Run > Run 'app' (Alt + Shift + X)
If you are running in release mode, when application started, to start debug, choose menu Run > Attach debugger to Android process > choose your process then go to your activity you want to debug again.
Related
In my first steps in exploring Android I now start with QR scanning.
Works all pretty well. But I am not able to come back from the ResultHandler after read the QR successfully to my MainActivity.
public class MainActivity extends AppCompatActivity implements
ZXingScannerView.ResultHandler
{
private ZXingScannerView mScannerView
....
#Override
public void handleResult(Result rawResult)
{
// my results are ok in rawResult
// the scanner does not scan anymore but it is still there
// how to go back to my main activity???
}
public void ClickButton (View view)
{
mScannerView = new ZXingScannerView(this);
setContentView(mScannerView);
mScannerView.setResultHandler(this);
mScannerView.startCamera();
}
}
}
I tried
mScannerview.stopCameraPreview
mScannerView.stopCamera
this.finish
setContentView(R.layout.activity_main); // shows my activity_main
// but I can not click anything
Thanks!!
EDIT
I added some code to describe it a bit better. The idea is from
https://www.numetriclabz.com/android-qr-code-scanner-using-zxingscanner-library-tutorial/
Your question isn't clear but I'm assuming you want to restart the scan process. Normally, you'd have to restart the SurfaceHolder to be in preview mode. Luckily for you the ZXingScannerView already has a method to do that. Call mScannerView.resumeCameraPreview(this) to restart the scan process.
Otherwise can you clarify? You say you want to go back but you're already in MainActivity
If you want to go back into activities/fragments stack you can try Activity.onBackPressed()
if you are in a fragment you must call this method against attached Activity
What do you want is not going back to your activity. You want to restore activity's layout.
I think the better choice is to add ScannerView to your activity's layout file with android:visibility="gone". Then in on click you can get this view and change it's visibility to VISIBILE.
Then when you have handled scanning result, you can reset yuoir ScannerView to visibility = GONE
I too was stuck with this problem for an hour, just like you. And later realised..
To solve this problem DON NOT implementing the ZXingScannerView in the same activity or fragment. Instead start a new activity when you click the button and this activity is just for the ZXingScannerView
Once the Scan is done finish and pass the data back to your activity or fragment
Just restart your MainActivity before this.finish()
the code below will start your main activity through intent...
worked fine for me
startActivity(new Intent(this,MainActivity.class));
this.finish();
remove from onCreate method this line setContentView(your layout) and when you finish scan write it after you stoped the camera then you can use your layout after scan
I had a bit of a look into android concepts and activities.
I put the QR handling in a 2nd activity and it worked well with the finish ().
Thanks for help anyway!!
I think it's too late, but I came with the same problem and I had so find a solution by myself.
You were on the right way, you need two steps more.
I called the methods where I link and set the listener of any buttons
There are the methods
Basically you were right where you set the content view, but you need to give the buttons their functionality back.
(I know its late, but better late than never). Good luck!
When turn the switch on it stays on.. however when i leave the activity and come back to it.. it goes back to off. I want it to stay ON OR OFF depending on whats last pressed. I have tried the code below but does not resolve my issue
SwitchButton.setChecked(true);
SwitchButton.setChecked(false);
What you need to do is override these methods in your activity:
#Override
protected void onSaveInstanceState (Bundle outState){
super.onSaveInstanceState(outState);
outState.putBoolean("CHECKED", SwitchButton.isChecked());
}
then in onCreate:
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstaceState);
if(savedInstanceState != null){
boolean isChecked = savedInstanceState.getBoolean("CHECKED");
SwitchButton.setChecked(isChecked);
}
}
If you are minimizing the activity and then returning back to it, and you want all controls to retain their states, then look into implementing saved instance state. This will persist the control values while you minimize / maximize the activity or rotate it. No data is permanently saved to the device. Sample code here:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
If you are closing the app completely and want the app to remember the settings, then consider SharedPreferences, which can be used to save data locally on the device. The data persists until your app explicitly deletes it or you uninstall the app. Sample code here:
http://developer.android.com/training/basics/data-storage/shared-preferences.html
If I'm bringing Android activities from the stack to the front, how do I refresh them? So to run onCreate again etc.
My code below, in conjunction with setting activities in the Android manifest to android:launchMode="singleTask" allows me to initiate an activity if that activity is not already active within the stack, if it is active within the stack it is then brought to the front.
How do I then, if the activity is brought to the front refresh it so that onCreate is ran again etc.
Intent intent = new Intent(myActivity.this,
myActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
I think FLAG_ACTIVITY_CLEAR_TOP will resolved your problem:
Intent intent = new Intent(myActivity.this, myActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
I don't think there is an explicit way to refresh onCreate, perhaps you may want to add the code you want reloaded into onResume.
This workaround may work if you want to keep your code in onCreate.
finish();
startActivity(getIntent());
If all you want to do is refresh the content, you should override the onResume method, and add in the code to perform the refresh in this method. To do this, use the following code within the activity that you want to perform the refresh, (ie, not the same activity that you are calling startActivity() from):
#Override
protected void onResume(){
super.onResume();
//add your code to refresh the content
}
Tip: If you are using Android Studio, press Alt+Insert (while you have the Java file open), then click Override Methods, find onResume, and it should provide you with a basic template for the method.
The diagram I added shows the order that the methods are run (this is known as the Activity Lifecycle). onCreate() is run whenever an Activity is first created, followed by onStart(), followed by onResume(). As you can see, when a user returns to an Activity, onCreate() is not run again. Instead, onResume() is the first method that is called. Therefore, by putting your code into the onResume() method, it will be run when the user returns to the activity. (Unlike onCreate(), which will not be run again).
Extra info: Since you will be initially setting the data in onCreate() and then refreshing it within onResume(), you might want to consider moving all of your code used to initially set the data to onResume() as well. This will prevent redundancy.
Edit: Based on your following comment, I can give the following solution:
I'm wanting to properly refresh the page, e.g. if there is a variable count initialised at 0. And though running the activity it's has became equal to 300. When the activity is called (intent) then refreshed, count will once again be equal to it's initial value. Do you know how to do this?
Without your current activity's code, there is not much to work with, but here is some pseudo-code as to how I would accomplish your problem:
public class MyActivity extends Activity {
TextView numberTextView;
int numberToDisplay;
#Override
protected void onCreate(Bundle bundle){
super.onCreate(bundle);
setContentView(myContent);
numberTextView = (TextView) findViewById(R.id.numberTextView);
numberTextView.setText(numberToDisplay+"")//converts the integer to a string
}
#Override
protected void onResume(){
super.onResume();
numberToDisplay = 0;
numberTextView.setText(numberToDisplay+"");
}
}
I start an activity A from B with an intent with extras and based on the type of extra in onCreate I do some process and it works fine.
But when I do a orientation change the same old intent is re-delivered by the system to me and the whole process gets restarted since I go through the onCreate once again.
My code completely take care of restoring the previous state of the activity when the onCreate gets called if no old intent is delivered to it. But since the system re-delivers it make my activity think it is a new intent and restarts the whole process once again.
I tried the flag intent.getFlags() != Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY. This flag prevents re-delivery in case of long press home button and activity launched from history but no effect on orientation change.
A dirty fix was proposed in another thread Dirty Fix but I am wondering if there is a proper way to address this problem.
Thanks in advance
Use savedInstanceState to determine if the activity or fragment is restored from whatever including orientation change.
savedInstanceState will be null when activity/fragment is restored.
public void onCreate(Bundle savedInstanceState) {
...
boolean isRedeliver = savedInstanceState != null || (intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0;
...
}
This technique is also used in official doc of fragment.
if (savedInstanceState == null) {
// During initial setup, plug in the details fragment.
DetailsFragment details = new DetailsFragment();
details.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
}
A 'clean' solution to this problem would be to use Fragments.
Create your own Fragment subclass.
In its onCreate, be sure to call setRetainInstance(true).
In its onCreate you can start your process.
If it is just for doing some work, return null in its onCreateView.
In your Activity's onCreate:
- First try to find the current instance of your own Fragment.
- If not found, create a brand new one and commit this to your Fragment Transaction.
By calling setRetainInstance(true) and by first trying to find it before creating a new Fragment in the Activity's onCreate, you keep the same Fragment instance even after a rotation and the Fragment's onCreate won't be called again.
Hey guys, i am making an android application where i want to show a dialog box about legal agreement everytime the application starts, i have a public method showalert(<>); which shows an alertdialog by building a dialog with alertbuilder. I added a call to showalert() method on the onCreate() method of the main activity to show it, but whenever the user rotates the screen, he gets the dialog everytime. The activity restarts itself when the phone is rotated. I tried adding android:configChanges="keyboardHidden|orientation" to my manifest but that doesnt help on this case. Also can i know how to register a new application class on manifest file. I am trying to create an application class and put the code to show dialog on the new class's oncreate method. But i am not being able to load the class when the app starts.
I also checked Activity restart on rotation Android but i dont seem to get a thing. I am pretty much a newbie to android programming, could someone simplify that for me?
Any help would be appreciated. :)
you could maybe look at the onRetainNonConfigurationInstance() activity method, which is called just before destroying and re-creating the activity on screen orientation change.
it allows you to retain an object that could for instance contain a test variable to know if your legal thing was already shown or not.. example :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String test = (String) getLastNonConfigurationInstance();
if (!("textAlreadyShown").equals(test)) {
//here : show your dialog
}
}
#Override
public String onRetainNonConfigurationInstance() {
return "textAlreadyShown";
}
Set the main activity to an activity that just shows the legal notice, when it is accepted/cleared, show a second activity ( which is currently the main activity )?