What may prevent the UI in android to be updated on time? - android

I'm developing an Android app that has to update it's UI depending on receiving and processing some server responses, I'm using runOnUiThread for that. I have like five activities in that app, all is working very well but one requires me to relaunch the Activity(like going to another one and then returning to it) or interacting with it in order to that update takes place, and that is the way i'm using with all the Activities including the infected one:
runOnUiThread(new Runnable() {
public void run() {
try {
response_received(response);
} catch (Exception e) {
e.printStackTrace(); // never catch any Exceptions
}
}
});
private static void response_received(JSONObject response) throws Exception{
try {
int volume_setted = response.getInt(volume);
Normal_Activity.volume_value.setText(String.valueOf(volume_setted)); // the Volume TextView updated efficiently
Infected_Activity.volume_value.setText(String.valueOf(volume_setted)); // has the problem mentioned above
} catch (JSONException ex) {
}
}
I'm pretty sure the problem is not in the TextView as all the Activity UI has this problem but i just posted an example.

Do not directly set values in a Activity from another Activity. If you want to pass data to Another activity always use Intents. check the below link
pass data from intent to an other intent
If you want to start another activity and get result back check the below link
http://developer.android.com/training/basics/intents/result.html

Related

How do i add a delay to program before running selection query to avoid bind value being null?

I keep getting an illegal argument exception when running my app. However, this happens prior to the Toast messages coming up and that's why I think I need a delay.
Prior to adding on the DatabaseHelper class, my app was running and the proper value was coming up on both Toast messages, the one in the MainActivity and the one showing the intent value passed in the DisplayResult activity.
I'm not sure what to do at this point.
Just do a thread sleep in a runnable.
int timeYouWantToSleep = 60000;
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(timeYouWantToSleep);
//do your work here
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
If this doesn't work, you know it's not a delay that you need.

Runtime error handling on android

I want to make some classes that catch runtime errors on android and offers the user the option to restore the last saved instance state of the app.
I was thinking of extending the Activity and Fragment classes and implement something that saves their state. In the meantime, another class handles every start of an activity or fragment, putting them in a stack.
I want to catch every possible exception in the app, hopefully making errors less bothersome for the user.
Any advice on how I should handle this?
How would this error checking influence the performance of an app?
It's not a good solution and i don't know if it's useful for you, but you can caught exceptions in Application Class.
public class MyApplication extends Application
{
public void onCreate ()
{
// Setup handler for uncaught exceptions.
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
#Override
public void uncaughtException (Thread thread, Throwable e)
{
handleUncaughtException (thread, e);
}
});
}
public void handleUncaughtException (Thread thread, Throwable e)
{
e.printStackTrace();
// do what ever you want.
}
}
You can use try catch blocks to catch runtime errors. If you use try catch efficiently with throws your app won't crash in first place hence no need to maintain stack of activities. btw maintaining stacks of previous activity in neither memory efficient nor advisable.

Thread.sleep() inside android application [duplicate]

I'm working on a memory game for Android and I'm having a problem. When the user taps the second image - if the images are not the same I want the second image to show for 1, 2 seconds.
What I've tried is to sleep for 1-2 sec. the UI thread after the second image is activated - but this doesn't seem to work - the second image doesn't seem to show! (only the first images is showed)
Here's my code:
public void whenTapedImage(View v, int position)
{
i++;
ImageView imgV=(ImageView)v;
if(i%2!=0)
{
firstClick=position;
imgV.setImageResource(im.images.get(firstClick));
}
else
{
secondClick=position;
imgV.setImageResource(im.images.get(secondClick));
try {
Thread.currentThread().sleep(1000);
if(!(im.images.get(firstClick).equals(im.images.get(secondClick))))
{
Toast.makeText(easyGame.this, "Try Again!", Toast.LENGTH_SHORT).show();
im.notifyDataSetChanged();
gridview.setAdapter(im);
gridview.invalidate();
aux=player1Turn;
player1Turn=player2Turn;
player2Turn=aux;
}
else{
done=done+2;
ImageAdapter.keepVisibleViews.add(firstClick);
ImageAdapter.keepVisibleViews.add(secondClick);
if(player1Turn==true)
{
player1Score++;
String score=Integer.toString(player1Score);
score1.setText(score);
}
if(player2Turn==true)
{
player2Score++;
String score=Integer.toString(player2Score);
score2.setText(score);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
What am I doing wrong?
You must not sleep the UI thread as this would prevent android from delivering any other events to your activity's UI.
Instead, do something such as use a timer and have the timer's method use the run on ui thread facility to make the desired postponed change.
For robustness you may need to implement a state machine (either formally, or in effect) to keep track of what is supposed to be happening - you'll need to decide if the current delay should be aborted or enforced if another button is pushed, and make the state machine treat that appropriately.
This is similar to Waiting in android app
Try following the solution posted there and use the Timer Class

Android UI Thread freezes waiting for socket in a simple client/server architecture

I think this is a quite common problem, but still I didn't find a satisfactory answer so I'm going to ask myself.
This is a piece of code:
// this is insine OnClickView
TextView status = (TextView) findViewById(R.id.status);
status.setText("Trying to connect to the server...");
try {
// this opens a socket and send a login request to the server.
int result = CommunicationManager.login(String email, String password);
switch (result) {
case CommunicationManager.SUCCESS:
// login ok, go on with next screen
break;
case CommunicationManager.WRONG_EMAIL:
status.setTextColor(Color.RED);
status.setText("Wrong Email!");
break;
case CommunicationManager.WRONG_PASSWORD:
status.setTextColor(Color.RED);
status.setText("Wrong Password!");
break;
}
} catch (CommunicationException e) {
status.setTextColor(Color.RED);
status.setText("Unable to estabilish a connection!");
} catch (ProtocolException e) {
status.setTextColor(Color.RED);
status.setText("Protocol error!");
}
This is what I would like to achieve:
User click Send button;
status textview shows "Trying to connect to the server...";
UI "waits" for communications to be over;
status textview shows result accordingly.
But instead when user clicks Send button, UI freezes (oddly before status text appears) until communication is done (I tried to connect to an unknown host).
A quick fix is to set a socket timeout, but I don't like this kind of solution: UI still freezes and which timeout should be set?
My first thought were Thread obviously, but as you can see I need to return a value, thing that in threading environment doesn't make much sense since threads run independently and asynchronously.
So what I need is definitely that UI waits for the service to be executed but without freezing.
By the way it seems to me that waiting for a return value means that UI has to wait for the task to be over, I just would not let it freeze.
I came across AsyncTask but I see two major disadvantages:
it seems to me that is too tightly coupled with UI;
what if I want to execute service with Integer, String and Boolean parameters? Should I extend AsyncTask<Object, Void, Void>?
Both leads to inextensibility.
What can I do to achieve my goal?
Please note that another request to the service will be a request for something that could not be ready yet, so I should automatically repeat request every few time (let's say ten minutes). So probably I'll need something I can use with TimerTask, but I'll still need to return a value to UI every time I execute that service (so I can update the status text and let the user know what's going on).
This is typical use case while dealing through external communication i.e. HTTP calls.
Best way is to use AsyncTask. To give you answers for your concerns for AsyncTask.
it seems to me that is too tightly coupled with UI;
Here good code design will play a role. You can write you own call back mechanism to get rid of tight coupling. Example can be below.
Create your version for request and response you need for WS call. It can be very simple primitive type or complex type parameters.
class Result{
//Define more para.
}
class Request{
//Deinf more para.
}
Write below callback interface.
public interface MyCallBack {
public void onComplete(Result result);}
Create AsyncTask and get above Interface object in constructor, same object can return Result object.
class LongRunningTask extends AsyncTask<Request, Integer, Long>{
private MyCallBack callback;
public LongRunningTask(MyCallBack callback) {
super();
this.callback = callback;
}
#Override
protected Long doInBackground(Request... params) {
// Perform your back ground task.
return null;
}
#Override
protected void onPostExecute(Long result) {
super.onPostExecute(result);
callback.onComplete(new Result()); //Here result is dummy but in real it should be contructred from doInBackground() method
}
}
Now last and important part to implement the interface and call asynctask. I am trying to reuse your code to have better clarity.
public class MainActivity extends Activity implements MyCallBack{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView status = (TextView) findViewById(R.id.status);
status.setText("Trying to connect to the server...");
}
private void onClick(){
//Similer to CommunicationManager.login(String email, String password); in your code.
LongRunningTask longRunningTask = new LongRunningTask(this);
longRunningTask.execute(new Request());
}
#Override
public void onComplete(Result result) {
try {
int result = result.getStatus
switch (result) {
case CommunicationManager.SUCCESS:
// login ok, go on with next screen
break;
case CommunicationManager.WRONG_EMAIL:
status.setTextColor(Color.RED);
status.setText("Wrong Email!");
break;
case CommunicationManager.WRONG_PASSWORD:
status.setTextColor(Color.RED);
status.setText("Wrong Password!");
break;
}
} catch (CommunicationException e) {
status.setTextColor(Color.RED);
status.setText("Unable to estabilish a connection!");
} catch (ProtocolException e) {
status.setTextColor(Color.RED);
status.setText("Protocol error!");
}
}
what if I want to execute service with Integer, String and Boolean parameters? Should I extend AsyncTask?
First Parameter is any user defined para. In case you need to pass multiple parameters then put them in to form of entity (i.e. - Class). Also, you can pass initial configuration parameter in constructor of AsyncTask i.e. - Communication URL.
Hope it will help.
Use multi threading, do all the communication in a different thread
Use worker thread, or AsyncTask for doing long-running operations.
Moreover, from Android Honeycomb, system throws exception, if you perform network operations on UI thread.

Queuing threads in Android

my app wants to update pictures on the web on a regular basis. This doesn't require UI feedback, so I just start a new Thread and let it run. The problem is, that this update-method may be called before the previous one has been finished. How can I make sure that the second call doesn't start a new thread but is queued and automatically started when the previous one finished? Are handlers the right solution here as well?
Here the code:
public static void updatePictureOnPicasa(final PictureEntry pe) {
new Thread() {
public void run() {
try {
if(pe.isUpdated())
picasa.updatePicture(pe.getUrl(), pe.getDescription(), pe
.getTags());
} catch (Exception e) {
Log.e(Prototype.TAG, "Unable to update picture on Picasa "
+ pe.getUrl());
}
}
}.start();
}
You can use a service feature in Android.Please refer these links:
http://www.brighthub.com/mobile/google-android/articles/34861.aspx
http://marakana.com/forums/android/examples/60.html
Hope this will help you.

Categories

Resources