iam doing a small chat app in android with socket .. I want the app in such a way that the socket should connect when we open the app and it should disconnect as soon as the user leaves the app..and the main thing is, it should be connected when user is at any activity in the app(example :profile, create groups or any activity other than conversation page) Like same thing in whatsapp and similar chat app..How this can be achieved?
thanks in advance
My trick, and I'm sure there are others, is to create an abstract BaseActivity with an activity counter and have all 'real' activities instantiate from this class:
abstract class BaseActivity extends Activity {
protected static int numForegroundActivities;
#Override
public void onStart() {
super.onStart();
numForegroundActivities++; // no need for thread sync
}
#Override
protected void onStop() {
super.onStop();
if (--numForegroundActivities == 0) {
doAppClosedCode(); // <----------------------------
}
}
}
// all instantiable activities should extends BaseActivity
class MainActivity extends BaseActivity ....
Hope it helps.
You can monitor when Activities are in the foreground by using this api:
Application.registerActivityLifecycleCallbacks
An Activity is in the foreground when onActivityStarted is called.
Related
I have two activities SplashScreen and MainActivity.
MainActvity download some data and show it.
Now I want to start both activities on application start, MainActivity in background and SplashScreen in foreground and when the data of MainActivity download complete I want to make MainActivity foreground and finish SplashScreen.
I have seen many solution but no one is going good in my situation.
Please give me some suggestion or example .
I think it's better to make splash screen to download data and when it completed show new activity (MainActivity). In onStart metod use downloaded data stored on phone.
Your example: The only way You can have resolve this your way is by start MainActivity first and from onStart start SplashScreen:
class SplashScreen extends Activitiy {
public void onStart() {
EventBus.register(this);
}
#Subscribe
public void finishedDownload(FinishedDownloadEvent) {
this.finish()
}
}
class MainActivity extens Activity () {
public void onStart () {
open(new Intent(SplashScreen.class)); // We would like to have
download();
}
public void download (OnFinish onFinish) {
... download
EventBus.post(new FinishedDownloadEvent());
}
}
I forgot:
class EventBus {
private final static Bus instance = new Bus();
public static void register (Object obj) {
instance.register(obj)
}
public static void post (Event obj) {
instance.post(obj)
}
}
EventBuss
In my application, bluetooth device scanning code is written in onResume() method in BaseActivity.
I extended some activities with BaseActivity so, if I switch to any activities, bluetooth scanning is being done.
Is there any way to write onResume() in BaseActivity works only once? Please help me. Thanks in advance.
Thats how inheritance works. But you can overwrite the onResume in your subclas with an empty method.
#Override
public void onResume(){
// no super class is called
}
But i think there is something wrong with your program design.
try this:
public class BaseActivity extends AppCompatActivity {
static Boolean IsResumecalled = false;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
super.onResume();
if (!IsResumecalled) {
IsResumecalled= true;
//write your code here
}
}
}
Your active Bluetooth connection should not reside in the BaseActivity. It rather should bind itself on his onCreate() via bindService to the BluetoothService - so it does not matter if one Activity destroys itself and the next one is getting started, because the Service is not Acitivity-dependent.
Look here for the general android developer guide on BluetoothService
https://developer.android.com/guide/topics/connectivity/bluetooth.html
And and how to use Services namely the bounded Service
https://developer.android.com/guide/components/services.html
There are also google code examples which you can use as a guideline.
It's a bad idea to block the onResume() call since it's a important part of the lifecycle for example if you minimize and maximize the app.
Override onResume in your child activities but do not call super.onResume()
#Override
public void onResume(){
// super.onResume(); // do not call this line in your child activities
}
I would like to know when my app is back from background. onResume() is not a good solution, because i have another activities beside the Main Activity, so it can back from background to each of them. The purpose is to use Google analytics and to know when a user is launching the app and also bring it back from the background.
Thank you all and much appreciation.
Create a common base class which extends Activity. Implement onResume() with the functionality you need. Then extend all of your other activities from this base class.
The onResume() in the base class should call super.onResume() and this should also be the first line in each of the individual activity onResume methods.
Base class
public class BaseActivity extends Activity
#Override
public void onResume(){
super.onResume();
// code to do your analytics stuff
}
Derived Activities
public class MainActivity extends BaseActivity
#Override
public void onResume(){
super.onResume();
// code for the individual activity
}
You can detect background application with ActivityManager.getRunningAppProcesses() which returns a list of RunningAppProcessInfo records. If your application is in the background check RunningAppProcessInfo.importance field equals to RunningAppProcessInfo.IMPORTANCE_BACKGROUND while RunningAppProcessInfo.processName is equals to your application package name.
More info:
http://developer.android.com/intl/es/reference/android/app/ActivityManager.RunningAppProcessInfo.html
The android.arch.lifecycle package provides an interface that let you know when the app is back from background.
Your application should implement the LifecycleObserver interface:
public class MyApplication extends Application implements LifecycleObserver {
#Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
#OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private void onAppBackgrounded() {
Log.d("MyApp", "App in background");
}
#OnLifecycleEvent(Lifecycle.Event.ON_START)
private void onAppForegrounded() {
Log.d("MyApp", "App in foreground");
}
}
To do that, you need to add this dependency to your build.gradle file:
dependencies {
implementation "android.arch.lifecycle:extensions:1.1.1"
}
As recommended by Google, you should minimize the code executed in the lifecycle methods of activities:
A common pattern is to implement the actions of the dependent
components in the lifecycle methods of activities and fragments.
However, this pattern leads to a poor organization of the code and to
the proliferation of errors. By using lifecycle-aware components, you
can move the code of dependent components out of the lifecycle methods
and into the components themselves.
You can read more here:
https://developer.android.com/topic/libraries/architecture/lifecycle
First I have a method which creates an activity which displays a view:
Intent intent = new Intent(viewController, TestActivity.class);
viewController.TestActivity(intent);
My TestActivity class calls setContentView(layout) and displays a view.
This works fine, my problem is trying to remove the Intent/View from the screen. I know I can call destroy() from within my Activity, however I am trying to remove the view from outside of the Activity class. I want the class which created the Activity/Intent to be able to remove it as well.
Any ideas? It seems like this should be a trivial fix however I'm unable to find the solution online for some reason. Thanks!
Make a sigleton-like pattern to get the instance of the started activity.
public class TestActivity extends Activity{
private static TestActivity instance;
public static TestActivity getInstance(){
return instance;
}
public void onCreate(Bundle savedInstanceState){
//xxxxx
super.onCreate(savedInstanceState);
instance = this;
}
protected void onDestroy(){
//xxxxx
super.onDestroy();
instance = null;
}
public void finishOutSide(){
this.finish();
}
}
Then in the outside,use these code to finish the activity:
if(TestActivity.getInstance() != null){
TestActivity.getInstance().finishOutSide();
}
All of your Activity instances can be destroyed when the sustem is running low on memory. Hence, it causes unexpected behaviour. Finish an Activity itside itself only or in a foreground Service that cannote be unexpectedly killed.
You have to rethink your application architecture to avoid such issue.
I'm designing an architecture where the app needs to execute certain set of operations everytime it goes to background (onPause) and a set of operations everytime it comes back to foreground (onResume), irrespective of the activity (for all the activities). Is there a way with which I can achieve this, without having to call those methods in every activity class' onPause and onResume overrides?
Make your own class that extends Activity and add your desired behavior to its onPause and onResume methods.
Then you extend that class on your activities.
public class BaseActivity extends Activity {
#Override
protected void onPause() {
// ...
}
#Override
protected void onResume() {
// ...
}
}
public class Activity1 extends BaseActivity {
// ...
}
You could extends your Activities by a BaseActivity which extends Activity, and create the two methods onPause / onResume in it.
See this answer for more information.