Android intent service onClick, or start new activity and then Asynctask - android

Many times in android apps, users click a button/view and start a new activity, where the new activity pops up in front of what the user was previously looking at, and loads data.
Would there be any difference from a user perspective if the data started loading (from network or disk or both) when the user clicked the button before the next activity started. And then that data was returned to the new activity in a broadcast receiver.
This is compared to starting the process in the oncreate of the activity. Assuming these network and i/o processes only take milliseconds either way, would it make a difference to the user if the methods were started in onCreate of the new activity, or started in the old activity onClick.
First way, starting I/O and changing views after I/O finishes
//first activity
public void onClick(View v){
startActivity(new Intent(this, NewActivity.class);
}
//NewActivity.class
onCreate(Bundle mBundle){
super.onCreate(mBundle);
setContentView(R.layout.mView);
mObject = networkCall(); //after network call, the view objects in this layout will reflect data from the network call
}
second way, starting the I/O in the first activity
//first activity
public void onClick(View v){
IntentService networkCall = new IntentService();
//start network call
startActivity(new Intent(this, NewActivity.class);
}
//second activity on create just sets the view and also broadcast receiver
My GUESS is that in the split second that it takes for the activity to pop up, the data from the intent service could become available. But at the same time, passing data via intent could take just as long making the benefits marginal
Insight appreciated

In my experience the onCreate() of your new activity is called almost instantly from when you call startActivity(). The new activity doesn't show up right way because it has to take time to render your layout.
You could play around with timings yourself by using the Log.d() function. Something like Log.d(TAG, "This happend at: " + System.currentTimeMillis()); at different points in your code to see when things happen. Watch the LogCat while your apps runs and you can decide for your self which way is better.

Related

How to preload Activity?

My aar has an Activity, and when I call the API, it creates an Activity every time.
also use the startActivityForResult function to get a response from the Activity.
button1.setOnClickListener(new Button.OnClickListener() {
Intent myActivity= new Intent(getApplicationContext(), myActivity.class);
myActivityOption option = new myActivityOption();
option.setType(2);
myActivity.putExtra("myActivityOption", option);
startActivityForResult(myActivity, REQUEST_CODE);
}
When MyActivity is created, it takes 2-3 seconds to draw a lot of images.
I want to make the delay occur only once.
I would like to be able to create an Activity without delays after initial init in the same form as class.
I'm sorry I missed my English.

Handling intent when receiving application is in the background

There 2 apps: First app can open the second one using:
Intent intent = getPackageManager().getLaunchIntentForPackage("com.my.path");
startActivity(intent);
this works fine.
Second app can call again the first app by using intents with actions. for example:
public void call(String number)
{
Intent myIntent = new Intent(Intent.ACTION_CALL);
myIntent.setData(Uri.parse("tel:" + number);
startActivity(myIntent);
}
And there lies a problem which I'll get to shortly.
I'm handling the received intent in the first app in the onCreate method. The first app is simply a single activity with many fragments which are switched with a fragment transaction. When receiving the intent from the second app, I'm making a transaction to a specific fragment according to the intent.
The problem is that when the first app is not in the background (meaning its close), my handling of the intent works fine. However, if the user opened the second app from the first one and the first one is still in the background, then when a user calls the intent in the second app, the first app is getting back to the foreground but to the same fragment the user was when he launched the second app, while I was expecting to show the new fragment which is based on the user's request in the intent sent from the second app.
Why is this happening and how can I fix it?
You could handle this by overriding the OnNewIntent method handling the intent and bringing to top the required fragment.

Passing current Intent as extra to another Activity

I have a problem with my Login screen. When it's started, I check for network connection, and if it's disabled, I want to show NoNetworkActivity. And the same for every other screen: when Activity is launched, I check network connection and navigate to NoNetworkActivity is needed. When navigating, I want to save the Intent which launched this previous activity and finish it to disable the Back button redirection when on NoNetworkActivity. So, when connection is restored, I want to launch that intent and get actual state of the app before this error:
LoginActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
if (!App.getInstance().isNetworkConnected()) {
Intent noNetwork = new Intent(this, NoNetworkActivity.class);
noNetwork.putExtra(NoNetworkActivity.EXTRA_FAILED_INTENT, getIntent());
startActivity(noNetwork);
finish();
}
...
NoNetworkActivity
private void checkNetworkConnection() {
mCheckButton.setVisibility(View.INVISIBLE);
mProgressBar.setVisibility(View.VISIBLE);
if (App.getInstance().isNetworkConnected()) {
Intent failedIntent = getIntent().getParcelableExtra(EXTRA_FAILED_INTENT);
startActivity(failedIntent);
finish();
} else {
mCheckButton.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.INVISIBLE);
App.toast("Connection failed");
}
}
And it's getting strange: startActivity(failedIntent) does NOTHING. I've tried to remove finish() from next line, and NoNetworkActivity just stays on top without anything happening.
And one more thing. You can suggest passing Activity actual class names instead of intents, but I realy need Intent. That's because I'm using a lot of starting actions for every activity and a bunch of extras.
Thanks in advance for any help. Cheers!
Very bad approach. Don't use it.
First, you don't need to finish previous activity just to disable Back action. You can override onBackPressed().
Second, you don't need to start parent activity again. Just call a new activity with startActivityForResult(); and override onActivityResult() callback.
Third, but most important. Why do you want to call a new activity just to show 'No Network' message? And what if network won't be re-established? Just create isNetworkEnabled() method and call it when user attempts to get data from the Internet, before sending actual request to server. If no network - notify a user with an alert or toast.
I suggest you use fragments instead of activities first of all.
Using fragments you can set retainInstance(true);
To disable coming back from an activity to the previous :
1)call finish() on that activity
2)
Intent i = new Intent();
i.setClass(this, MyActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);`
It works with an explicit Intent.
In LoginActivity substitute:
noNetwork.putExtra(NoNetworkActivity.EXTRA_FAILED_INTENT, getIntent());
with:
noNetwork.putExtra(NoNetworkActivity.EXTRA_FAILED_INTENT, new Intent(this, LoginActivity.class));
Btw, Alexander Zhak has some good points in his answer

Transmit variables from service at onDestroy() to already opened Main-Activity

I have a Main-Activity which displays several spinners.
With a Toggle-Button in the Main-Activity I start a service which collects GPS-Data in background that measures the distance and sets some other variables.
When I stop the service with another click on the Toggle-Button in the Main-Activity, I stop the service, so the onDestroy() command is executed in the Service.
Within onDestroy in the Service, I want to submit the variables from the service to the already opened Main-Activity.
I tried that so far without success in the service:
Intent intent = new Intent(this, Main.class);
Bundle b = new Bundle();
Test = 2222;
b.putInt("Test", Test);
intent.putExtras(b);
I do not use the "startActivity(intent);", cause the activity that should the data send to is already open...the Main-Activity.
And on the side of the Main-Activity:
Bundle b = getIntent().getExtras();
if (b != null){
Test = b.getInt("Test");
}
else{
//..oops!
Toast.makeText(Main.this, "Oops...Nothing from service! :(", Toast.LENGTH_SHORT).show();
}
I never get data from the service.
I am trying this cause I need to start the service from the Main-Activity, from the Main activity the user stops the service and gets the values from it, then the Main-Activity should transmit the values from the service AND from the selected spinner values from itself to another activity.
I am trying that now for days and I also find some hints here, but nothing worked for me so far.
Someone any ideas?
Do I have to use a Broadcast-Receiver?
Whats the correct way to do this?
Before destroying the service store the data in shared preference and access it in the main activity
I don't know if this is the best way, but just have the Service you created update a static pojo. If the activity is already open then you could just set a timer to poll a the static pojo from the Activity to see if something has changed through an AsyncTask. When something has been updated in the pojo the AsyncTask can tell the Activity to update the UI accordingly. Then you don't have to play around with silly bundles. Also if your worried about your data getting lost you could always use SQLite. Hope this helps.
You need a broadcast receiver in main activity to get the data.

Android event timing (Toasts and Intents)

I'm trying to explicitly launch an intent to a new Activity, but I would like some code in the current Activity to finish executing first. I've done a bit of research, and have a couple of ideas to accomplish this but am thinking "there's gotta be an easier way to do this". Here is the relevant block of code:
cpuToast(dmg);
if (player_.getStatus() == false)
{
playerWon_ = false;
Intent intent = new Intent(Main.this, Death.class);
startActivity(intent);
}
dmg is an int. cpuToast simply makes a String to display the damage and then calls show(). getStatus() returns whether or not the player was killed. In the event that player was killed, I launch a new intent which will play an animation of the players death. Unfortunately the "Death" Activity is being launched before the Toast even becomes visible, and then it becomes visible during the Death Activity which I do not want.
Does anyone know a simple way to ensure that the Toast executes fully prior to launching the Death Activity? From what I've found it looks like I'll have to create a "Timer" object when really all I want is a simple while loop like "while(Toast.isVisable) {}" to tie up the execution for a couple of seconds.
Some example code for updating the UI in response to timed events can be found at http://developer.android.com/resources/articles/timed-ui-updates.html.
At the time you begin your toast, you can also post a delayed message to your current activity; the runnable of that delayed message can start the new intent.
Does it have to be a toast?
If you are up for the idea of using a custom dialog (removed title, buttons etc.) that is probably your best bet. Use a handler to dismiss the dialog after given time and start the new activity.

Categories

Resources