Android app: How to remove a view displayed by an Activity? - android

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.

Related

What is the use of Android static inner activity class and where exactly we can use?

I have created a Activity called MainActivity Which extends from ThirdActivity.
Next, I have an inner static activity called AnotherActivity which extends from SecondActivity. Below is my code:
1)MainActivity: which is the first activity that calls at first when app loads.
public class MainActivity extends ThirdActivity {
public static class AnotherActivity extends SecondActivity{
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("Main Activity");
}
}
2) ThirdActivty Code follows:
public abstract class ThirdActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
System.out.println("Third Activity");
}
}
3) Inner static activity extended from SecondActivity which consists of:
public abstract class SecondActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
System.out.println("Second Activity");
}
}
Now the output of the above android program is:
Third Activity
MainActivity
In order to access the inner activities we need to do declare in manifest as:
<activity android:name="MainActivity$AnotherActivity" ></activity>
So, My question goes like this:
1) How to access Static inner Activity classes.
2) When to use this scenario.?
3) Will the inner activity runs the life cycle process and what happens to already running MainActivity?
I love answering bizarre questions before having coffee.
1) How to access Static inner Activity classes
What do you mean by "access"? The fact that this is a static inner class is pretty much irrelevant. It will run like an normal Activity. When it is running, its onCreate method, e.g., will be called. When that happens, there is a reference to the running instance of AnotherActivity in the canonical variable this.
2) When to use this scenario.
I can't think of a single reason. In fact, I can think of a million reasons not to use it. Ever.
3) Will the inner activity runs the life cycle process and what
happens to already running MainActivity?
Yes. The "inner" activity will run through a normal Activity lifecycle. Nothing happens to the MainActivity because it is not running when the AnotherActivity is running. When AnotherActivity is started, MainActivity is stopped (onPause, maybe onStop, etc).

Android: NullPointerException in dialog when rotating

Sorry if this been asked before but I couldn't find an answer to my specific case. Also sorry that I'm new and a little stupid.
Problem:
I'm showing a dialog from a fragment and passing along a context in my constructor method because I need a context in my dialog to register for broadcastrecievers etc.
DialogFragment fragmentDialog = MyDialog.myConstructor(getActivity());
fragmentDialog.show(getFragmentManager(), "dialog");
Then in MyDialog class I store the context in a instance variable.
The problem arises when rotating the device and I get a nullPointerException when I try to use the context again in the dialog.
Can this be solved in some easy way?
If the device is rotated the Activity will be destroyed and recreated. So the Context you passed to your Fragment points on the Activity which was destroyed.
You could use setRetainInstance(true) in your Fragment. This way your Fragment will survive the recreation of the Activity.
To solve the NPE you have to pass the Context to the Fragment, if the Activity is recreated. Then the Context belongs to the new Activity.
In fact, without this update every line of code which points on the Activity like getActivity() or getFragmentManager() will lead in a NPE.
You get the NullPointerException because activites are destroyed and recreated when rotating the screen.
The SO post below gives more info...
https://stackoverflow.com/a/1673374/
Please be careful with the order of events if you rotate a FragmentActivity, because this can also be a source of NullPointerExceptions.
This is not documentated:
When the FragmentActivity is created the first time,
public class MyActivity extends FragmentActivity implements
MyFragment.OnFragmentInteractionListener {
private int var1;
private int var2;
#Override
protected void onCreate(Bundle savedInstanceState) {
//before
var1 = 3;
super.onCreate(Bundle savedInstanceState)
//after
var2 = 5;
}
//Interface Methods
public int getVar1() { return var1; }
public int getVar2() { return var2; }
}
both of the [before] and [after] code will be run before the fragments are attached and created. So, if you get the vars in the onCreate() call of the Fragment you get both vars. But when you rotate your device, the Activity is recreated from the savedInstanceState in the super call. Now, the fragments are reattached and created anew in this call! That means, this time the Methods of the Listener Interface are called before your [after] code. So, if you pass the Context of the activity to the fragment and get Information through the Interface like it is shown in: https://developer.android.com/training/basics/fragments/communicating.html
you get a NullPointerException for var2 because the interface methods are called from the fragments onCreate() onAttach() ... functions before the [after] code in the Activity's onCreate() is executed! So, take care that you set your Information the InterfaceFunctions are accessing before the super call.
Depending on what you're doing in your initialization you could consider creating a new class that extends Application and moving your initialization code into an overwridden onCreate method within that class.
public class MyApplicationClass extends Application {
#Override
public void onCreate() {
super.onCreate();
// TODO Put your application initialization code here.
}
}
And you are not stupid, even experts need help from time to time.

Android Libgdx app startes only after resinstall or reboot

The main problem is that the app starts only after installation or reboot.
Second time the application does not run correctly.
Details are below.
I have encountered with a few strange problems
1) Libgdx did not detect screen size correctly on Android 4 in
SCREEN_WIDTH = Gdx.graphics.getWidth();
I got 369*320 instead of 960*540
I do as follows to fight with this problem:
I run main Activity class, where I get screen size using Display
Then I run AndroidApplication class where I start Admob and Libgdx class.
2) The second problem is that the app starts
with no initialized values, that is to say with the same memory.
No initialization of values such as boolean abc=false;
Looks like invalid exit?
In Libgdx class (third class) I set some value exit=true and exit,
disposing all textures. Program returns to the second class .
public void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Data.exit) finish();
Second class returns to main activity
which checks exit in the same manner
3) Next interesting thing is that now Gdx.graphics.getWidth()
gets screen size correctly. Mistery...
4) If so, I remade the app.
And now main class starts Libgdx class.
It works and exits good, but only first time after installation or reboot.
Seconds time Libgdx onCreate starts, but render() does not.
Looks like invalid exit after first start again:
The main class code is here
public class MyActivity extends AndroidApplication
implements IActivityRequestHandler {
public void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
context.startService(new Intent(context, BillingService.class));
....
// Create the libgdx View
View gameView = initializeForView(new MyGame(this), false);
// Create and setup the AdMob view
adView = new AdView(this, AdSize.BANNER, "aaaaaaa");
}
#Override
public synchronized void onPause() {
super.onPause();
}
#Override
public void onStop() {
super.onStop();
}
#Override
protected void onDestroy() {
super.onDestroy();
}
Any ideas? Thanks!!
You are using statics. They preserve their value when you close the app, and you open it again before Android destroys the process, hence using the same VM. You cannot control when Android will destroy it, so try to initialize these variables in the constructor/create method of their class.
Instead of:
static boolean abc=false;
Use:
static boolean abc;
public MyClass/create(){
abc=false;
}
Or do not use statics unless necessary.

Create static reference to Context, Use it everywhere and finally let Garbage Collected

I have a little problem about needing Activity/Application everywhere...
More precisely I have classes defined like this:
public class MyApp extends Application {
private static Activity currentActivity;
private static MyApp instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static void setCurrentActivity(Activity activity) {
currentActivity = activity;
}
}
And I have an Extended activity like this:
public class MyActivity extends Activity {
....
#Override
public void onResume() {
super.onResume();
MyApp.setCurrentActivity(this);
}
....
#Override
public void onDestroy() {
super.onDestroy();
MyApp.setCurrentActivity(null); // for nullifying static reference
}
}
My questions are:
Is the above code snippet fair ?
Should I use super.onDestroy(); after the MyApp.setCurrentActivity(null); to verify that activity is not reffered and destroyed succesfully?
And most important, what about static reference instance? where can I nullify it to not prevent from GC ?
Thanks.
Is the above code snippet fair ?
Nope. The biggest problem is in MyActivity.onDestroy(). This can be called at any time when the activity is no longer in use (ie: after it has finished). If you null out currentActivity in onDestroy() you will not be clearing the reference to MyActivity, you will be clearing the reference to whatever activity happens to be currently active at the moment. I you really want to have currentActivity point to the current activity, the best you can do is something like this:
#Override
public void onPause() {
super.onPause();
if (MyApp.getCurrentActivity() == this) {
MyApp.setCurrentActivity(null);
}
}
Also, be aware that there is a small window between onPause() of an activity and onResume() of the next activity so that it is possible that currentActivity will be null during this time. Watch out for that!
Should I use super.onDestroy(); after the
MyApp.setCurrentActivity(null); to verify that activity is not
reffered and destroyed succesfully?
See my comment above. You cannot null out this reference in onDestroy().
And most important, what about static reference instance? where can I
nullify it to not prevent from GC ?
You don't need to. There is only ever one instance of MyApp created and it lives for as long as your process exists. When Android doesn't need your process anymore it just kills the process, which will clean up everything automagically.

Finish Activity() from a separate myJavaClass.java

I have tried almost all the solutions from SO but no success :(.
I have a simple myJavaClass.java with a couple of functions.
One of the functions in myJavaClass : startActivity() starts MyCustomActivity
public startActivity(Context context)
{
Intent intent = new Intent(context, MyCustomActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
}
This launches MyCustomActivity() as expected.
Now I have another function in myJavaClass.java to close/finish MyCustomActivity but it is not able to do so!
I have tried
Making MyCustomActivity SingleTop in manifest and creating the activity via an intent as above
Passing an activity instance to "this" in onCreate() of MyCustomActivity and calling MyCustomActivity.activity.finish() from myJava.class but that doesnt work as well
Please help me. I have been stuck here for hours now. I know the solution is very simple and conceptual but I am a newbie. Just building Java/Android concepts!
EDIT
MyCustomActivity
public Activity activity;
OnCreate()
{
...
this = activity;
}
MyJavaClass
public closeActivity(Context context)
{
Activity customActivity = MyCustomActivity.activity;
customActivity.finish();
}
I think that what you are trying to do is fundamentally bad. For a start, outside of the Activity code, there are no guarantees that the activity still exists - the memory manager may have cleaned it up, the user may have pressed Back etc. Think of Activities as independent entities - you can start them, and you can optionally get a result back when they finish what they're doing, but that's it.
Think about whether you really have to programmatically close the activity from outside it - I'd say this is an unusual design, but there are circumstances where it may be appropriate.
If so, what I think you want is a publish/subscribe system whereby MyCustomActivity can register a listener with MyJavaClass, and then receive a callback whereupon it can 'finish' itself.
public Activity activity implements FinishListener
{
public void onCreate(...)
{
//where does MyJavaClass come from? see in a minute
MyJavaClass myjava = getMyJavaclass();
myJava.addFinishListener( this );
}
public void onFinishCallback()
{
this.finish();
}
}
and
public class MyJavaClass
{
private List<FinishListener> finishListeners = ...;
public void addFinishListener( FinishListener fl )
{
this.finishListeners.add(fl);
}
public closeActivity(Context context)
{
for ( FinishListener fl : finishListeners )
{
fl.onFinishCallback();
}
}
}
and
public interface FinishListener
{
void onFinishCallback();
}
Now the only remaining issue is how to get MyJavaClass from the Activity. That's up to you - you may already know how, you may be able to put it in your Application implementation, it could be a singleton (bad), the listeners could be static (bad) or various other options.
Oh, and don't forget to remove the listener again in the Activity's onDestroy() method!
Just try this....
public closeActivity(Activity _activity)
{
_activity.finish();
}
you can't finish activity from other class until you have the reference of instance of Activity in that class, give the reference in that class and call finish() method to stop the activity.
activity.finish();

Categories

Resources