Flurry context in a Fragment - android

I need to use Flurry within a Fragment in my Android app.
I insert the following code in onStart():
#Override
public void onStart() {
super.onStart();
//Log.i("About get activity","About get activity "+getActivity().hashCode());
FlurryAgent.onStartSession(getActivity(), "WXXXXXXXX");
}
and in on stop:
#Override
public void onStop() {
FlurryAgent.onEndSession(getActivity());
super.onStop();
}
Is this code correct? Do I pass the context as getActivity(), this or something else?

That's correct, you could also use:
getActivity().getApplicationContext();
which is the context for the entire application and not specific to that particular Activity.
As a side note, if it happens to you to get some weird crashes, specially when you press quickly the back button removing all the fragment in your back stack, it may be that getActivity() is returning null.

Related

OnResume from specific activity

Im integrating TapResearch in my Android app. As mentioned here in the documentation https://www.tapresearch.com/docs/android-integration-guide that the to show the survey I need to use TapResearch.getInstance().showSurvey();. This method open an activity from the library.
In the documentation there is a listener onSurveyModalClosed() so I can put anything once the activity is finished, but this listener does not work.
Since onSurveyModalClosed() does not function. In the MainActivity I want the app to do something OnResume from TapResearch Activity.
#Override
protected void onResume() {
If the resume happens upon returning from TapResearch Activity {
Do something.
}
}
I think this is the activity path import
com.tapr.internal.activities.survey.SurveyActivity;
This may not be the best answer available but a workaround as this is the only thing I found for myself.
Whenever a specific activity is launched, I set a boolean variable as True in OnCreate() of that launched activity using TinyDB (sample code below), and when returning back to MainAcitivity, I check whether the variable is true and if true, then a specific code is executed.
In OnCreate() of launched activity:
TinyDB tinydb = new TinyDB(this);
tinydb.putBoolean("isMyActivity",true);
And in OnResume() of MainActivity:
#Override
protected void onResume() {
if(tinydb.getBoolean("isMyActivity")) {
yourMethod();
}
super.onResume();
}
You can use SharedPreferences to store the boolean or a public static boolean variable. I use TinyDB for many things. This works great.

What is the best approach to call register/unregister eventbus on fragments?

I'm brand new using Event Bus from otto lib, So far I created a Event Bus Singleton class, which I'm using in several parts of my code. Now I'm working on a fragment view, But I still have a question, regarding:
When is the best time to register/unregister my event bus?
In a couple of posts I read that onStart() and onStop(), but without any specific reason why.
public class SomeFragment extends Fragment {
#Override
public void onStart() {
super.onStart();
EventBusSingleton.register(this);
}
#Override
public void onStop() {
super.onStop();
EventBusSingleton.unregister(this);
}
}
If I follow the same approach as in the activities doing the call onResume() and onPause() works fine as well.
public class SomeFragment extends Fragment {
#Override
public void onResume() {
super.onResume();
EventBusSingleton.register(this);
}
#Override
public void onPause() {
super.onPause();
EventBusSingleton.unregister(this);
}
}
What could be the potential risk(if exist) from each call way?
onPause()/onResume() is called when your activity does not have the focus anymore but could still be visible (think a dialog or alert on top of your activity).
onStop()/onStart() is called when your activity is not visible anymore.
Which one to use depends your use case. I believe it's not really a problem to have callbacks executed while in the paused state so I would just put the register/unregister in onStop()/onStart() but if you really want to make sure, you can put them in onPause()/onResume().
My problem was what my fragmets had two instances for bad coding, y delete de uneccesary instance and it solve the problem

NullPointerException in Fragments onAttach for findViewById

So I have a curious problem I'm not able to solve right now.
RoomGamesFragment
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
roomActivity = (RoomActivity) activity;
gameTabContainerView = (LinearLayout) roomActivity.findViewById(R.id.game_tab_container); // findViewById returns null
// NullPointerException
gameTabContainerView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
This works totally fine when opening the activity which contains the fragment. But here is the problem: If I leave the activity open, put the app in the background (by clicking the home button), use other apps and then open my app again after some time, I get the NullPointerException, because findViewById returns null now.
How can I prevent this? Is the Activity removed from the stack, which leads to the Exception? I know I could just check for null, but I need the onClickListener, even when I return to the app after it has been in the background.
You should not perform this code in onAttach() but rather in onActivityCreated(). This is because the "View" is not yet created. onAttach() is above the onCreateView() in the Fragment lifecycle.
For more info : http://developer.android.com/guide/components/fragments.html#Creating

Why do OnCreate should be called only once on the start of Activity?

I would like to know, why OnCreate() is called only once at the start of an activity?
Can we call OnCreate() more than once in the same activity?
If yes, than how can we call it? can anyone give an example?
Thanks a lot!!!
Why would you want to called it again? unless the activity is reconstructed, which is called by system. You cannot call OnCreate manually , it is the same reason why you won't call setContentView() twice. as docs:
onCreate(Bundle) is where you initialize your activity. Most
importantly, here you will usually call setContentView(int) with a
layout resource defining your UI, and using findViewById(int) to
retrieve the widgets in that UI that you need to interact with
programmatically.
Once you finish init your widgets Why would you?
UPDATE
I take some words back, you CAN do this manually but I still don't understand why would this be called. Have you tried Fragments ?
Samplecode:
public class MainActivity extends Activity implements OnClickListener {
private Button btPost;
private Bundle state;
private int counter = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
state = savedInstanceState;
btPost = (Button) findViewById(R.id.btPost);
btPost.setOnClickListener(this);
Toast.makeText(getBaseContext(), " " + counter, Toast.LENGTH_LONG)
.show();
}
#Override
public void onClick(View v) {
counter++;
this.onCreate(state);
}
}
onCreate() method performs basic application startup logic that should happen only once for the entire life of the activity .
Once the onCreate() finishes execution, the system calls the onStart() and onResume() methods in quick succession.
The initialization process consumes lot of resources and to avoid this the activity once created is never completely destroyed but remains non visible to user in background so that once it is bring back to front , reinitialization doesn't happen .
Where you want to call onCreate manually.
Then just do this.
finish();
Intent intent = new Intent(Main.this, Main.class);
startActivity(intent);
finish() calls the current stuff.
And if you are doing somethong getExtra in this activity then do this,
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("key",your_variable);
super.onSaveInstanceState(outState);
}
And add this to your onCreate()
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
if(savedInstanceState != null)
{
your_variable= savedInstanceState.getString("key");
}
}
Why would you want to call onCreate more than once? You will be re-creating the activity. If this is what you need for whatever reason then finish the activity and use an intent to create a new instance of that activity. Otherwise, you have two instances of the activity at the same time. Hope that helps but if that doesn't make sense then add more information as to what you want so we have context
OnCreate is basically use to create your activity (UI). If you have already created your activity then you need not create it again as you have already created.
It is basically used to initialize your activity and to create user interface of your activity. Activity is a visual part which you can use again and again so.. I think your problem is not to recreate activity but to reinitialize all components of your activity. For that purpose you can create a method initialize_act() and call it from anywhere...
#OnCreate is only for initial creation, and thus should only be called once.
If you have any processing you wish to complete multiple times you should put it elsewhere, perhaps in the #OnResume method.
Recently i realized that onCreate is called on every screen orientation change (landscape/portrait). You should be aware of this while planning your initialization process.
Recreation can be suppressed in AndroidManifest.xml:
<activity
android:configChanges="keyboardHidden|orientation"
android:name=".testActivity"
android:label="#string/app_name"></activity>

Activity group does not refresh activities when back button is clicked

I have a tabhost on my application and I'm using an Activity group which handles 3 activities inside.
Example:
ActivityGroup Handles
A -> B -> C
When i start this activities i'm using the flag Intent.FLAG_ACTIVITY_CLEAR_TOP.
My problem is when the user goes from A->B->C and press back button, my B activity shows up, but it does not resume or reload or refresh. It has the same state as before.
For example if the user goes again to C, C is refreshed, but when from C goes back.... B is not.
On B I have implementend methods such as onResume, onStart, onReestart and debugging it the main thread never goes in there...
And i need to refresh B because C can make changes that change the content displayed on B.
I have googleled this for 3 days and I couldn't found a solution..
I had this problem too.
I was using ActivityGroup code based on this blog post.
When I pressed the back button the pervious View would load fine, but the activity associated with it would not fire the onResume().
I was using an extended activity with on overridden and public onResume().
I found this blog post, so tried casting the view as my extended activity and called onResume().
Bingo.
Edit.... here's some more detail...
public class YFIMenuListActivity extends ListActivity {
....
#Override
public void onResume() {
super.onResume();
}
....
}
onResume() is normally protected, but I override it and make it public so that my ActivityGroup can call it.
I only have extended list activities in this activity group (I was just playing around). If you have different activities, each will have to override onResume() and I guess you'd have to look at the type of context you got back from v.getContext() before casting and calling it.
My ActivityGroup looks something like this:
public class BrowseGroup extends ActivityGroup {
.....
#Override
protected void onResume() {
super.onResume();
// call current activity's onResume()
View v = history.get(history.size()-1);
YFIMenuListActivity currentActivity = (YFIMenuListActivity)v.getContext();
currentActivity.onResume();
}
....
}
I've managed to implement an expanded version of cousin_itt's approach.
In both of my activities being used within the activity group I changed onResume from :
protected void onResume()
to
public void onResume()
I then wrote the following onResume function in my ActivityGroup to manually fire off onResumes:
#Override
protected void onResume() {
super.onResume();
View v = history.get(history.size()-1);
MainPeopleView currentActivity = null;
try {
currentActivity = (MainPeopleView)v.getContext();
currentActivity.onResume();
}
catch ( ClassCastException e ) {
Log.e(TAG, e.toString());
}
ProfileView otherActivity = null;
try {
otherActivity = (ProfileView)v.getContext();
otherActivity.onResume();
}
catch ( ClassCastException e ) {
Log.e(TAG, e.toString());
}
}
I have to say, this feels like the worst android hack I've ever written. I'm never using activitygroup again.
((ReportActivity)getLocalActivityManager().getActivity("ReportActivity")).onResume();
ReportActivity is that name you want to back Activity
ps: v.getContext();
only return the ActivityGroup ,it can't invoke child Activity onResume
I have found that onFocusChanged(boolean hasFocus) is great for situations like ActivityGroup. This will fire, even if onResume() does not. I use it for a few of my apps that have TabHosts and ActivityGroups. Here you can force the refresh and insure that it always gets fired when your Activity regains the focus.
I hope you have write your refresh data code in this method onResume().

Categories

Resources