App Goes Background When MainActivity Class Called - java

I'm learning Android Development with multiple app's source codes. I opened one of my projects in Android Studio. I developed some part of this app using some open source libraries from GitHub. My problem is app is compiling and I'm able to build APK but when I run it on a device the goes to background (not crashed because when I checked the logcat there is no trace for a crash).
When I'm running the app firstly the SplashScreen class getting loaded (There is no issue with it). After splash screen loaded it should open MainActivity class but it goes to background (As I already said that's not even a crash)
Here's SplashActivity's code :
public class SplashActivity extends BaseActivity {
private void runSplash() {
new CountDownTimer(TimeUnit.SECONDS.toMillis(3), 100) {
public void onTick(long j) {
onFinish()
}
public void onFinish() {
SplashActivity.this.startActivity(new Intent(SplashActivity.this, MainActivity.class));
SplashActivity.this.finish();
}
}.start();
}
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_splash);
runSplash();
}
protected void onDestroy() {
super.onDestroy();
}
}
UPDATE: The issue is now resolved. The problem is with exception handling inside the onCreate method. Whatever exception happens then the activity getting finished (finish();). Thanks for helping me to understand.
After Splash Activity finished MainActivity Should be shown but the app goes background. I even tried ignoring Splash Activity and just MainActivity as a Launcher in Manifest file. But the same problem (As soon as app launched it goes to background)

In your MainActivity onCreate(), you've a huge try/catch block, and if an Exception raise, you finish() the activity...
You have to log the Exception with Log.e("YOUR_TAG", e.getMessage()) to understand your bug :)

Related

Activity of my app goes into background sometimes after I turn off the screen

I am running Camera as a service attached to an activity. There are other services such as upload and Firebase are running along with the camera service. Now my requirement is to keep the service running after I turn off the screen. I am acquiring PARTIAL_WAKE_LOCK too. The services run perfectly for the initial 10 or 12 minutes. After that, the app stops sending any logs to ADB. In the device, the app goes to the background by itself. Not even onPause or onDestroy is logging anything. The logs just stop coming to Android Studio. For resuming the normal functioning I have to manually open the app again,
These are the things that I have already tried,
1.Given permission of acquiring PARTIAL_WAKE_LOCK.
2.Setting android:largeHeap="true"
3.Foreground services
According to Doze mode documentation it ignores wake locks.
Also starting from Android Pie it is impossible to gain camera access from background app.
Also according to android developer guidelines you must free camera, when you app is paused, because it will block all other apps.
onSaveInstanceState function should be called in these situations, check with you and if its called then open the activity again with the delay.
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
try {
Intent intent = new Intent(getBaseContext(), YourActivity.class);
startActivity(intent);
finish();
} catch (Exception ex) { }
}
}, 200);
}

App crashes after onTaskRemoved executed

I edited the question so it's not a duplicate
of this
In MainActivity I am doing some file operations. These operations are processed in a single file. So, after that I pass the file through intent at ForceShut. This is because I want to detect when user swipes the app out from recent apps which is to say onTaskRemoved() is called, into which this file is deleted. Now no problem so far. The file is successfully transmitted through the intents, and onTaskRemoved() is called as seen from the Logs. Also the file which I try to delete in onTaskRemoved() is successfuly deleted when I swipe the app and the Logs in there all run fine until the "Application Terminated" shows. But few seconds after, I get a crash alert saying App has stopped while app was even removed from the recent. The crash though appears twice in a row then no crashs appear further on. What could be the problem ? :(
My MainActivity class looks like this
public MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//several file operations go here <--
//removed for simplification
Intent mIntent = new Intent(this, ForceShut.class);
mIntent.putExtra("file", file);
startService(mIntent);
}
}
and ForceShut class looks like this :
public class ForceShut extends Service {
File file;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
file =(File) intent.getExtras().get("file");
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent){
if(file.exists())
file.delete();
}
}
EDIT
So as #CommonsWare was suggesting I had forgotten to look at the LogCat, instead I was looking only at the "Run" tab logs. So I looked it over and it seems like there is a null pointer exception :
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Bundle android.content.Intent.getExtras()' on a null object reference so it seems like even after swiped onStartCommand is called again. Why could the service start over even after app was swiped ?
EDIT 2
Question is not a duplicate, as #Andreas has pointed out. I edited the question. However I found the workaround myself. I shut down the Service with stopSelf() as it seems like swiping the app out of Recents sort of doesn't get rid of the service which ocasionally restarts. Anyway hope this helps anyone
Why could the service start over even after app was swiped ?
You have started a "sticky" service. The system will automatically restart any sticky service until it is explicitly stopped.
#Override
public int onStartCommand(Intent intent, int flags, int startId){
file =(File) intent.getExtras().get("file");
return START_STICKY;
}
I don't see where you actually stop it with stopSelf().
As far as your NullPointerExceptions, simply check if the objects exist before trying to read from them.
if (intent != null && intent.hasExtra("file"))
file =(File) intent.getExtras().get("file");
The service restarts because of the START_STICKY inside onStartCommand.
You need to use START_NOT_STICKY instead to prevent the service from restarting.

Decide which activity to start from a subclass of Application

I have a simple application in which before I do anything, I must check whether the user is logged in or not.
To do this, I inherited the Application class like this:
public class GBApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
if (userIsLoggedIn()) {
Intent overviewActivity = new Intent(this, Overview.class);
overviewActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(overviewActivity);
}
}
}
userIsLoggedIn() returns a boolean stored in the SharedPreferences file.
Everything works, but when I press back from the Overview activity, it redirects me to the default activity (MainActivity), and removing it from the AndroidManifest.xml files gives error.
Also, I can't call finish() since this is a non activity class.
How can I terminate my program after I return from the Overview class? I found solutions where they pass a value to the MainActivity, call finish() from there. But this seems to complicated.
What else I can do?
This is my application tag in AndroidManifest.xml
Your plan is going to cause problems. Every time your process is created, you are starting an activity, even if an activity is not needed for this particular process.
Displaying a launcher activity — such as in response to the user tapping on a home screen launcher icon — is one way that a process might be created for your app. But there are many others:
AlarmManager
JobScheduler
a Notification
a push message (e.g., from Firebase Cloud Messaging)
a request sent to a ContentProvider that you export from your app
a request sent to a Service that you export from your app
a manifest-registered BroadcastReceiver
the user returning to your task in the overview screen
and so on
In none of those scenarios is displaying this activity necessarily appropriate. Yet, your code will display the activity in all of them, because any time Android forks a process for your app, you display this activity.
Have all of your activities (other than the login one) see if the user is logged in, and route the user to the login activity if that is needed. When the user completes the login, and the login activity finishes, the user is returned to where they were trying to go, whether that is your launcher activity or some other activity (e.g., they returned to your task after your app had been in the background for a while, so your process was terminated, but Android tries to send them back to whatever activity of yours they had been in last).
You could simply override the onBackPressed() of your overviewActivity and pilot the direction your app goes when the back button is pressed (which in your case is to shut down the app):
#Override
public void onBackPressed(){
startActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
The code above just shuts down your app immediately the back button is clicked once (which is pretty boring.. but simple). You could also try the code snippet below; it pops up a dialogue box:
#Override
public void onBackPressed(){
new AlertDialog.Builder(this)
.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id){
startActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
})
.setNegativeButton("No", null)
.show();
}

How to kill Android app 100% when hitting Back

I'm developing on a Galaxy S6 running Lollipop. I used Android Studio to create a ScrollView app using the template that comes with Android Studio. I only added the following Java code:
#Override
public void onBackPressed() {
Toast.makeText(this, "onBackPressed", Toast.LENGTH_SHORT).show();
super.onBackPressed();
}
#Override
protected void onPause() {
Toast.makeText(this, "onPause", Toast.LENGTH_SHORT).show();
super.onPause();
}
#Override
protected void onStop() {
Toast.makeText(this, "onStop", Toast.LENGTH_SHORT).show();
super.onStop();
}
#Override
protected void onDestroy() {
Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show();
super.onDestroy();
}
When I tap Back on the device, all 4 toast messages come up in the sequence that they appear in the code. However, when I view the app in Application Manager, the Force Stop button is still enabled, indicating that the process is still active. To confirm that I also downloaded a third party app to view active processes and it shows mine in the list.
Is there something that has to addes so that when hitting the Back button on the device the process will die 100% and not be on that active processes list any longer?
This is expected behavior on Android.
Android makes no guarantees as to when it will kill your app when exiting, so I'm not sure why you think it's supposed to. It's more beneficial for Android to keep your app in memory as long as possible so that its's faster to resume.
Please this code in your OnBackPressed() method:
int pid = android.os.Process.myPid();
android.os.Process.killProcess(pid);
That way your app will be completely closed and removed from running apps.

Kill app whenever it goes to background

I am creating an app. From MainActivity -> Fragment -> See Details Activity.
It is working fine.
But when I am going to background on See Details Activity, it is still running.
Why this activity or app is not getting destroyed. I want to kill the app whenever I will go to background.
Add this:
#Override public void onPause() { super.onPause(); // Always call the superclass method first
Finish();
}
Invoke finish() method before start Fragment

Categories