Am new in android .. am trying to implement thread in a android. But am getting error .. I googled and getting answer "AsyncTask", but truly i dont know how to implement
Error message
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
my code
final Thread thread = new Thread(){
#Override
public void run() {
try {
DatabaseHandler dbh = new DatabaseHandler(test.this);
result=dbh.Verify(1);
if(result != ""){
getData();
progress.dismiss();
}
else{
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
Use following code to run in UI thread.
Runnable runnable = new Runnable() {
#Override
public void run() {
handler.post(new Runnable() { // This thread runs in the UI
#Override
public void run() {
DatabaseHandler dbh = new DatabaseHandler(test.this);
result=dbh.Verify(1);
if(result != ""){
getData();
progress.dismiss();
}
else{
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
new Thread(runnable).start();
Seems like you need to create your handler in MainActivity and then pass it further. Like so:
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
}
Related
If i have something like example.com/time.php and the output is just 20000 so How can i link this to control time of refresh, Any Idea?
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(10000); // here is the number which should be linked to the webpage output
runOnUiThread(new Runnable() {
#Override
public void run() {
// update View here!
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
You should use handler for easier implementation.
Handler handler = new Handler();
Runnable test = new Runnable() {
#Override
public void run() {
//do work
handler.post(test, 4000); //wait 4 sec and run again, you can change it programmatically
}
};
public void stopTest() {
handler.removeCallbacks(test);
}
public void startTest() {
handler.post(test,0); //wait 0 ms and run
}
thread = new Thread(new Runnable() {
#Override
public void run() {
synchronized (datahandler) {
while (true) {
try {
if (datahandler.getCount() > 0) {
commitData();
}
datahandler.wait();
} catch (InterruptedException e) {
e.printStackTrace();
Log.e("Service", e.toString());
}
}
}
}
});
thread.start();
Commitdata to connect and commit data form datahandler to server. But I dont kow why it shows not respone dialog. If I do not close it, it continouns to commit. Why UI is influenced when I commit data in other thread
public class ThreadsLifecycleActivity extends Activity {
// Static so that the thread access the latest attribute
private static ProgressDialog dialog;
private static Bitmap downloadBitmap;
private static Handler handler;
private ImageView imageView;
private Thread downloadThread;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create a handler to update the UI
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
imageView.setImageBitmap(downloadBitmap);
dialog.dismiss();
}
};
// get the latest imageView after restart of the application
imageView = (ImageView) findViewById(R.id.imageView1);
Context context = imageView.getContext();
System.out.println(context);
// Did we already download the image?
if (downloadBitmap != null) {
imageView.setImageBitmap(downloadBitmap);
}
// check if the thread is already running
downloadThread = (Thread) getLastNonConfigurationInstance();
if (downloadThread != null && downloadThread.isAlive()) {
dialog = ProgressDialog.show(this, "Download", "downloading");
}
}
public void downloadPicture(View view) {
dialog = ProgressDialog.show(this, "Download", "downloading");
downloadThread = new MyThread();
downloadThread.start();
}
// save the thread
#Override
public Object onRetainNonConfigurationInstance() {
return downloadThread;
}
// dismiss dialog if activity is destroyed
#Override
protected void onDestroy() {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
dialog = null;
}
super.onDestroy();
}
static public class MyThread extends Thread {
#Override
public void run() {
try {
// Simulate a slow network
try {
new Thread().sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
downloadBitmap = downloadBitmap("http://www.devoxx.com/download/attachments/4751369/DV11");
// Updates the user interface
handler.sendEmptyMessage(0);
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}
}
//==========================
You can sea in code that handlers are used to post message on GUI thread. further you can read about it over here
http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html
Also Read This http://android-developers.blogspot.de/2010/07/multithreading-for-performance.html
I am trying to combine two simple application that I found on the net.I have a thread and after 5 seconds my sensor lists should be displayed with a Toast message.But Nothing happens ..Thread is not working I think I messed up everything.Could you please help. I would really appriciate
public class MainActivity extends Activity{
List<String>sName=new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "Loadingg", Toast.LENGTH_LONG).show();
Thread thr=new Thread(){
#Override
public void run (){
try {
sleep(5000);
StringBuilder message=DisplaySensors();
Toast.makeText(getApplicationContext(),message, Toast.LENGTH_LONG).show();
} catch (Exception e) {
// TODO: handle exception
}
}
private StringBuilder DisplaySensors() {
SensorManager sm=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
List<Sensor>sList=sm.getSensorList(Sensor.TYPE_ALL);
StringBuilder sb=new StringBuilder();
for (int i = 0; i <sList.size(); i++) {
sb.append(((Sensor)sList.get(i)).getName()).append("\n");
}
return sb;
}
};
thr.start();
}
All UI operations have to run on Main UI Thread. So if you want to show a toast message, this shouldn't done in a seperated Thread. In this case, toast message has to be in runOnUiThread() block as seen below.
public class MainActivity extends Activity{
List<String>sName=new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "Loadingg", Toast.LENGTH_LONG).show();
Thread thr=new Thread(){
#Override
public void run (){
try {
sleep(5000);
StringBuilder message=DisplaySensors();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),message, Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
private StringBuilder DisplaySensors() {
SensorManager sm=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
List<Sensor>sList=sm.getSensorList(Sensor.TYPE_ALL);
StringBuilder sb=new StringBuilder();
for (int i = 0; i <sList.size(); i++) {
sb.append(((Sensor)sList.get(i)).getName()).append("\n");
}
return sb;
}
};
thr.start();
}
You should not use the Toast in a Thread. Use runOnUiThread instead:
See this
#Override
public void run (){
try {
Thread.sleep(5000);
StringBuilder message=DisplaySensors();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),message,Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
This is my scenario. A class A implements Runnable. When user click a button, there will show a progress dialog and call the method searchMap() to search an address. The dialog dismisses after 10 seconds. I really misunderstand how to execute the run() method. this is my creepy code.
public class AddLocationMapActivity extends MapActivity implements Runnable {
private ProgressDialog progressDialog;
private MyHandler myHandler;
private Message msg;
#Override
public void run() {
mapCurrentAddress();
}
public void mapLocation(View v) // click event here{
progress();
Thread thread = new Thread(this);
thread.start();
}
private class MyHandler extends Handler{
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what) {
case NOT_OK_MESSAGE: // Fail
alert(AddLocationMapActivity.this, message());
progressDialog.dismiss();
break;
case OK_MESSAGE: // Success
found(); // Point to the appropiate address
progressDialog.dismiss();
break;
case EXPTION_MESSAGE: // Exception
alert(AddLocationMapActivity.this, "Unexpected error");
progressDialog.dismiss();
break;
}
}
}
protected void mapCurrentAddress() {
String addressString = addressText.getText().toString();
Geocoder g = new Geocoder(this);
List<Address> addresses;
myHandler = new MyHandler();
msg = myHandler.obtainMessage();
try {
addresses = g.getFromLocationName(addressString, 1);
if (addresses.size() > 0) {
//address = addresses.get(0);
msg.what = OK_MESSAGE;
myHandler.sendEmptyMessage(OK_MESSAGE);
} else {
// show the user a note that we failed to get an address
myHandler.sendEmptyMessage(NOT_OK_MESSAGE);
}
} catch (IOException e) {
// show the user a note that we failed to get an address
//e.printStackTrace();
myHandler.sendEmptyMessage(EXPTION_MESSAGE);
}
}
private void progress() {
progressDialog = ProgressDialog.show(this,
"Checking", "Contacting Map Server");
Thread progressThread = new Thread();
progressThread.start();
}
}
When click event occurs, the program fails with exception Uncaught Handler
here's a little bit of my threading code that doesn't give away too much...
progress = ProgressDialog.show(this, "", "Loading...", true);
new Thread(new Runnable() {
#Override
public void run()
{
// get some network content
Chooser.this.runOnUiThread(new Runnable() {
#Override
public void run()
{
progress.dismiss();
// update the UI
}
});
}
}).start();
How to make Async task execute repeatedly after some time interval just like Timer...Actually I am developing an application that will download automatically all the latest unread greeting from the server and for that purpose I have to check for updates from server after some fixed time intervals....I know that can be easily done through timer but I want to use async task which I think is more efficient for android applications.
public void callAsynchronousTask() {
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
PerformBackgroundTask performBackgroundTask = new PerformBackgroundTask();
// PerformBackgroundTask this class is the class that extends AsynchTask
performBackgroundTask.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 50000); //execute in every 50000 ms
}
//Every 10000 ms
private void doSomethingRepeatedly() {
Timer timer = new Timer();
timer.scheduleAtFixedRate( new TimerTask() {
public void run() {
try{
new SendToServer().execute();
}
catch (Exception e) {
// TODO: handle exception
}
}
}, 0, 10000);
}
You can just a handler:
private int m_interval = 5000; // 5 seconds by default, can be changed later
private Handle m_handler;
#Override
protected void onCreate(Bundle bundle)
{
...
m_handler = new Handler();
}
Runnable m_statusChecker = new Runnable()
{
#Override
public void run() {
updateStatus(); //this function can change value of m_interval.
m_handler.postDelayed(m_statusChecker, m_interval);
}
}
void startRepeatingTask()
{
m_statusChecker.run();
}
void stopRepeatingTask()
{
m_handler.removeCallback(m_statusChecker);
}
But I would recommend you to check this framework: http://code.google.com/intl/de-DE/android/c2dm/ Is a different approach: the server will notify the phone when something is ready (thus, saving some bandwidth and performance:))
wouldn't it be more efficient to create a service and schedule it via Alarm Manager?
The accepted answer is problematic.
Using TimerTask() for activating async task via handler is a bad idea. on orientation change you must remember to cancel also the timer and the handler calls. if not it will call the async task again and again on each rotation.
It will cause the application to blow up the server (if this is rest http get request) instead of X time - eventually the calls will be instance many calls on each second. (because there will be many timers according to the number of screen rotations). It might crush the application if the activity and the task running in background thread are heavy.
if you use the timer then make it a class memebr and cancel it onStop():
TimerTask mDoAsynchronousTask;
#Override
public void onStop(){
super.onStop();
mDoAsynchronousTask.cancel();
mHandler.removeCallbacks(null);
...
}
public void callAsynchronousTask(final boolean stopTimer) {
Timer timer = new Timer();
mDoAsynchronousTask = new TimerTask() {
#Override
public void run() {
mHandler.post(new Runnable() {
...
Instead try to avoid async task, and if you must then use scheduler service to run the async task. or the application class such as in this nice idea:
https://fattybeagle.com/2011/02/15/android-asynctasks-during-a-screen-rotation-part-ii/
Or use simple handler (without the timer, just use postDelayed) and also good practive is to call cancel the async task onStop(). this code works fine using postDelayed:
public class MainActivity extends AppCompatActivity {
MyAsync myAsync = new MyAsync();
private final Handler mSendSSLMessageHandler = new Handler();
private final Runnable mSendSSLRunnable = new Runnable(){
..
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
mSendSSLMessageHandler.post(mSendSSLRunnable);
}else
..
#Override
public void onStop(){
super.onStop();
if ( progressDialog!=null && progressDialog.isShowing() ){
progressDialog.dismiss();
}
mSendSSLMessageHandler.removeCallbacks(mSendSSLRunnable);
myAsync.cancel(false);
}
private final Runnable mSendSSLRunnable = new Runnable(){
#Override
public void run(){
try {
myAsync = new MyAsync();
myAsync.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
}
mSendSSLMessageHandler.postDelayed(mSendSSLRunnable, 5000);
}
};
class MyAsync extends AsyncTask<Void, Void, String> {
boolean running = true;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show
(MainActivity.this, "downloading", "please wait");
}
#Override
protected String doInBackground(Void... voids) {
if (!running) {
return null;
}
String result = null;
try{
URL url = new URL("http://192...");
HttpURLConnection urlConnection = (HttpURLConnection)
url.openConnection();
InputStream in = new BufferedInputStream (urlConnection.getInputStream());
result = inputStreamToString(in);
}catch(Exception e){
e.printStackTrace();
}
return result;
}
#Override
protected void onCancelled() {
boolean running = false;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progressDialog.dismiss();
try {
..
} catch (JSONException e) {
textView.append("json is invalid");
e.printStackTrace();
}
}
}