Why can't we just call new Activity() - android

So, kind of a noob situation, but today, out of curiosity, I tried to do something like:
new Activity().runOnUiThread( new Runnable{...})
mostly because i don't actually have access to any activities (working on a 3rd party library). I just have the applicationContext, which i don't think allows me to make that runOnUiThread call.
So i guess i'm kind of wondering if there is a way to somehow fake out a minimally-invasive activity just so i can run something on the UI thread (or do other things, like pop up dialog...etc.) ??
if not, does anyone know what's wrong with just making new Activity() ? ( i mean, aside from the fact that, yes, i will get a null pointer because i haven't set my base context since the onCreate for the activity never got called ). if possible, i would like to accept an answer that can provide a little more detail and more "context" (no pun intended)

new Handler(context.getMainLooper()).post(new Runnable()
{
#Override
public void run()
{
}
});

Activity is managed by Android OS and is not meant to be used this way, to do so would mean breaking the API contract so don't expect it to behave correctly.
If you want to show some dialog, just create an Activity with transparent background, to the user it would be the same as a single Dialog floating above another screen.

Related

If the app uses serveral thread, will it run smoothly than using one UI Thread?

My Application is using Single Thread( UI Thread ) right now,
and it has some code like...
keep checking my phone state
google map service
keep adding marker to current state
and there's a "popupmenu"
and when the "Popupmenu" inflates, app frame drops.
I've never tried splitting a Single Thread to two, is this the right way to prevent the janky(laggy) frame?
Or is there something like alternatives?
No, more threads are probably not the answer here.
First of all the android gui is single threaded, you are only allowed to interact with it using the main thread.
Are you doing something similar to the official doc/guide here for popup menu?
https://developer.android.com/guide/topics/ui/menus#PopupEvents
Meaning code something lik this:
public void showMenu(View v) {
PopupMenu popup = new PopupMenu(this, v);
// This activity implements OnMenuItemClickListener
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.actions);
popup.show();
}
If you are not doing much more than this you can't optimize this much more, not easily.
If you are, perhaps you can simplify it to the basic example from the docs.
I would otherwise assume that you are consuming too much of the frames' time budget doing other things that hopefully can be optimized/paused instead so the popup menu inflating is not going over your limits.

How to perform work in background in android without loosing results?

I need to perform long running task. In that task I would copy something from one place to another.
I've tried to use IntentService for that, but the problem is that it can be killed and I will lose all work in that case. I know that I could tell the system that I need to restart it ASAP, and the service could know about it, but I need to start work exactly from where I was left.
It's not so difficult to do that in "stupid way". Say I use some persistent storage to store some "pointer" to the point where I left and somehow start working from that point.
But the thing is I would need to do a lot of work to do that. Like recompute progress to display in notification. Also it would require serious rewrite of the code which now looks like that.
public class Exporter implements ElementExporter {
#Override
public void exportElements(ReadableElementStorage from, WritableElementStorage to) throws IOException {
while (from.hasNextElement()) {
Element element = from.loadElement();
to.saveElement(element);
}
}
}
I think that there should be some framework to do long running task, which could be cancelled and restarted after some crash.
Or maybe you would suggest a better design?

Opening WebView in background

This is the first time I ask something, so if there is something wrong just tell me and I´ll try to fix it ASAP.
We have a customer that wants us to login in their servers with a native Android app, but without giving us a custom way to do this. They want us to use the current website they have to log and, after authentication takes place, retrieve within the browser a XML which contains the data we need. After that, use the data in the native app. All of this with the user not knowing/seeing that a browser is being used. A total mess IMHO.
Of course, I have never tried this approach in the past and my first tests make me feel like this is impossible (or extremely difficult) to achieve. Whenever I try to load the URL in a hidden WebView the default browser pops up showing the website.
My main question is, is it possible to load a webview and work with it (invoke javascript, etc...) in the background?
Thank you.
You could set the WebView to hidden by default with the attribute android:visibility="gone", interact with it at runtime then when you need to show it to the user after you've loaded data, just call setVisibility(View.VISIBLE)
Hope this helps!
Ofc, you must to use a Thread :
protected void getPage(){
Thread th = new Thread(){
public void run(){
//Download and make things
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
//print int the activity
}
});
}
};
th.start();
Remember, and thats is VERY important, you CANT draw from thread to the main activity. The only who can draw in the screen is the main activity. You can draw with 2 methods:
One , with the method _mActivity.runOnUiThread(new Runnable() {_ like the example i put.
Two, use a Handler to send messages from thread to main activity with the information that you want to draw.
*Main activity is the activity that its in the screen in that moment, not the first activity of the app

Undefined result when opening managed dialog in AsyncTask when in background

I have a problem that causes me some problems when a user (or another app, like the phone-application) pushes my application to the background.
My application does following:
A User can enter some information that is supposed to be pushed to a server.
When the user clicks "Send" i open a managed ProgressDialog and start an AsyncTask that performs the server communication.
When server communication is complete the AsyncTask reports back to my Activity where i perform a dismissDialog().
Directly after dismissDialog(), I will show another managed dialog using showDialog() that will inform the user about whether the submission was ok or if it failed.
This all works perfectly without any issues; however, when a call happens to come while the AsyncTask is running I get (seemingly random) one of these results:
The activity holding the managed dialog is dismissed completely and the previous view from the stack is presented when I come back.
The activity holding the managed dialog is still on screen, but it is grayed out without showing a dialog. The only way to fix this is to rotate the phone at which point it shows the "Submission sent"-dialog exactly the way it should and everything is ok after that.
All this happens without any warning messages so I get absolutely no clues as to why Android is behaving this way.
I know a way around this and that is to cancel the AsyncTask (so no dialogs are shown at the end). However, in this very use-case the requirements are that the app has to try to complete the server transaction so that there is as little confusion as possible (i.e. the user wondering if it was really sent or not).
Has anybody else had this issue and knows a way around?
I see recommendations to hold a reference to the asynch task in onRetainNonConfigurationInstance
What to do with AsyncTask in onPause()?
Or implement a bus:
https://github.com/commonsguy/cwac-bus/tree
EDIT: The complexity of your challenge is two fold:
1) saving and restoring state of your app on a kill such as when there is an incoming phone call
https://sites.google.com/site/jalcomputing/home/mac-osx-android-programming-tutorial/saving-instance-state
2) somehow continuing the asyncTask on kill instead of canceling it onPause
https://sites.google.com/site/jalcomputing/home/mac-osx-android-programming-tutorial/asynch
Both of these are significant challenges alone, and trying to fix both at the same time would give me a headache. In fact, I am getting a headache just thinking on it :) One clue is that you say the dialog returns on orientation change. This MAY be due to the fact that using the standard architecture for dialogs, the OS handles saving and restoring the state of dialogs for you on orientation change.
[EDIT] See CommonsWare
#Override
public Object onRetainNonConfigurationInstance() {
task.detach();
return(task);
}
and
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bar=(ProgressBar)findViewById(R.id.progress);
task=(RotationAwareTask)getLastNonConfigurationInstance();
if (task==null) {
task=new RotationAwareTask(this);
task.execute();
}
else {
task.attach(this);
updateProgress(task.getProgress());
if (task.getProgress()>=100) {
markAsDone();
}
}
}
where task is an instance of
static class RotationAwareTask extends AsyncTask<Void, Void, Void> {
I see no reason why this would not work for all types of soft kills, but on a hard kill, well, you get killed. Dead is dead :)
Without looking at your code it is slightly difficult to say what the problem is. However, here is something you could use to help get around the problem. You can override the onPause() method of your Activity.
This is taken directly from the Android Acitivy javadoc:
onPause() is where you deal with the user leaving your activity. Most importantly, any changes made by the user should at this point be committed (usually to the ContentProvider holding the data)

More threads and orientation changes questions

When it comes to threads and orientation changes, it seems the normal thing to do is something like this:
public class Bwent extends Activity {
private static Bwent instance;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
instance = this;
}
//...
That way, if you're making a network request with a thread, and someone changes the orientation of the phone, the thread will know to use the new Activity.
However, is it possible that the thread could finish during the time Android is destroying the old Activity and creating a new one?
Is there a moment in the process where the thread still might be pointing to the wrong Activity, or a partially destroyed activity?
It seems like there shouldn't be, but even using a Handler created in the main thread, I'm having intermittent issues with a thread trying to update an object that no longer exists. It's rare, but it does happen.
When it comes to threads and
orientation changes, it seems the
normal thing to do is something like
this:
It is a thing to do. I am not certain whether or not it is the "normal" thing to do. I am dubious that it is the best thing to do.
However, is it possible that the
thread could finish during the time
Android is destroying the old Activity
and creating a new one?
Yes. There is nothing in your code preventing it.
Is there a moment in the process where
the thread still might be pointing to
the wrong Activity, or a partially
destroyed activity?
Yes. There is nothing in your code preventing it.
Instead, try the pattern that I illustrate here. Use an AsyncTask, implemented as a static inner class or a public class. Have it be the one that knows about the Activity. Have it only use the Activity in doPostExecute() (or possibly onPublishProgress()). From the way AsyncTask and Handler work, our understanding is that the AsyncTask will always have an Activity in those on-the-main-thread methods.
Some of this stuff was discussed recently.

Categories

Resources