Need to simulate tab change scenario from an android test project - android

In my app, I've got 3 tabs. On clicking on each individual tab, some tab specific task happens. Now I am supposed to test the scenario of changing tabs from an android test project. In order to do that, I've called getTabHost.setCurrentTab(int tabIndex) method. But an error has been thrown saying
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

The exception is quite self explanatory: "Only the original thread that created a view hierarchy can touch its views." In other words, you're trying to change the current tab from a different thread than the one that created it. More specifically, you have to do this action on the widget from the GUI thread - the thread that created the view hierarchy.
So you either have to move your setCurrentTab(int tabIndex) call to the GUI thread, or use a message mechanism. The latter is usually done using a Handler. Plenty of good examples and code snippets 'out there' that can show you how to go about this.

Related

Exactly what operations can only be done on the user interface thread?

So I understand that any changes to the UI need to be on the main thread for an Android application. And also, you should use other threads to do work so that the UI doesn't freeze up. But some of the work I want to do is preparing UI elements which will be shown later on. I want to get those things ready on a separate thread and then enable a button once its done - that way the user won't be able to access it until it's ready BUT they'll be able to use the main page quickly.
Exactly what operations count as changing the UI? I want to do as much preparation in the background so that the first part of the app ready can be shown ASAP while other parts are still loading.
For example, it seems like findViewById is fine, but what about creating/modifying Views, setting listeners, setId, setEnabled and so on? If I newly create a Button which hasn't been added to a parent, can I setText on it in a background thread?

How to restart rendering thread of GLSurfaceView (or what to do instead)?

I'm experimenting with ways to do classical mobile game paradigm: a selector of levels, followed by a game screen.
I fully understand that there are plenty of ways to do that, but i was wondering about what goes wrong when i try this particular one (for learning purposes):
I have an activity, which holds references to my own GLSurfaceView child. On the activity start it loads a default 'level' and perfectly plays it. I can see Render thread started.
I implemented an OptionsMenu item, which after activation inflates a GridView with proper adapter, which allows user to select a level; and sets this inflated Layout to Activity by using setContentView. This is when GLThread dies.
Now i also implemented the OnClick's of that menu so that after click it loads a level in the game engine (works fine, btw) and brings back GLSurfaceView by using setContentView with saved (in 1.) reference.
And that's how i get a blank screen. Everything works fine, menu still works, i can go back to level selector, but in debugger i can see Render Thread doesn't exist.
Please, could someone explain to me what exactly goes wrong here? I'm totally not sure about this OpenGL intrinsic.

is it possible to use view instead of UI Thread?

I m new in android.
i have a little bit confusion in SurfaceView and View......
According to my knowledge..
Views are all drawn on the same GUI thread which is also used for all user interaction.
I want to knw is it possible to create separate thread for the handling
Depends on what you define in handling.
If in handling you mean doing calcualtions, downloads etc. then yes.
If by handling you mean splitting control and view up, then no.
If your handling means that handling GUI things in other than GUI thread then Its not possible as Views are coupled with GUI thread or Android Component Activity. But non GUI threads alive even when your activity is finished , and It may leak the references to views. So it has been avided in al most all Programming models. Suppose if you are downloading the some values in Non GUI thread and then update your GUI views and in bwteen your screen orientation takes place and Your activity and its views are recreated but Non GUI thread is till now keeping the reference to old views . This can create old views to not to be collected by Garbage Collector and leak memory .

Android: Making a simple animation set

I am making an interactive walkthrough for one of my apps, and in a couple of spots an alpha animation and some various other UI changes (such as checkbox pressed states) would be really great.
The walkthrough has a back and next button. The basic idea is that the next button would start the animation (maybe as a thread?), and if at any point in the animation the back button was pressed, that the animation would stop.
I have looked into the built in Android animation library, but have sort of seen a lot left to be desired. My next thought was a thread, but I know I can't change the UI from an outside thread. Also I want to leave the UI thread open for my back button listener.
Any thoughts on how these simple animations could be achieved?
You're right you can't update UI elements directly from another thread. But you can do this indirectly with Handlers. Handlers are basically a type of IPC that allows you to queue up messages to the UI for proceessing. So what you do is basically create a Handler in your Activity and pass this handler to your process thread. When there's something you want to update in the UI from the process thread just do mHandler.sendEmptyMessage(UPDATE_SOME_VIEW).
Take a look at handlers here.

Inflate a view in a background thread

I have a very simple question:
Is or is it not possible to inflate a view (not add it to layout) in a background thread (ex: in the doInBackground of an AsyncTask)?
I know that it is possible, because I have implemented most Activities in my application this way and never had a problem, until I had this problem on a Galaxy S: Android: android.view.InflateException: Binary XML file line #13: Error inflating class <unknown> in SAMSUNG Galaxy S
I've been told that I should not inflate Views in background threads, but what are the specific reasons and why does my aproach work in most devices but not in Galaxy S?
The LayoutInflater does not make any assumptions about what thread it runs on. And nothing is mentioned about this in its documentation. Also its code seams to be thread-agnostic.
On the other hand, Views that are created by LayoutInflater might instantiate Handlers in their constructors. Well, they probably shouldn't do that, but there is no requirement for them to not create/use Handlers in their constructors.
My guess is that Samsung Galaxy S had some modifications in its EditText that somehow triggers creation of Handler (according to crash log from your other question instance of GestureDetector was instantiated which in turn created new Handler). While default implementation doesn't do this.
Overall, I'd say that because there is no explicit requirement for Views to not use Handlers and Loopers in their constructors you can't assume inflating Views from non-UI thread is safe.
You can actually create HandlerThread and try inflating Views inside it. But I'd say this is very risky, as in Samsung Galaxy S example the view assumes that this thread will be alive during View lifetime and will process all messages using its Looper. Which might result in crash later on.
With latest support lib you can use android.support.v4.view.AsyncLayoutInflater to inflate views asynchronously. Be careful though that it can fallback to inflating on UI thread if specific requirements are not met:
For a layout to be inflated asynchronously it needs to have a parent whose generateLayoutParams(AttributeSet) is thread-safe and all the Views being constructed as part of inflation must not create any Handlers or otherwise call myLooper(). If the layout that is trying to be inflated cannot be constructed asynchronously for whatever reason, AsyncLayoutInflater will automatically fall back to inflating on the UI thread.
Is or is it not possible to inflate a view (not add it to layout) in a background thread (ex: in the doInBackground of an AsyncTask)?
Possible, yes. Recommended? No. As mentioned in the documentation:
Thus, there are simply two rules to Android's single thread model:
Do not block the UI thread
Do not access the Android UI toolkit from outside the UI thread
via: Processes and Threads
Update [02/06/19]:
Apparently, the support library has a tool to do this:
AsyncLayoutInflater (Jetpack version). It was introduced in version 24, around 2016 (2 years after my answer)
But, as mentioned on other answers, be careful with this tool as it can very easily backfire.

Categories

Resources