I need to show a second activity after the progress bar is filled. I tried the code below but it doesn't show the progress bar and just shows my second activity.
This is the code:
public class MiSuper2 extends Activity {
String strListas[] = null;
private ProgressBar mProgress;
private int mProgressStatus = 0;
private Handler mHandler = new Handler();
private StoreData stdArticulos = null;
public Cursor cursor = null;
private long fileSize = 0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
stdArticulos = new StoreData(this);
fileSize = 0;
setContentView(R.layout.main);
stdArticulos = new StoreData(this);
cursor = stdArticulos.leerArticulos();
mProgress = (ProgressBar) findViewById(R.id.progressbar_activity);
new Thread(new Runnable() {
public void run() {
while (mProgressStatus < 100) {
mProgressStatus = doWork();
mHandler.post(new Runnable() {
public void run() {
mProgress.setProgress(mProgressStatus);
}
});
}
}
}).start();
if(cursor.moveToFirst()) {
do{
strListas[cursor.getPosition()] = cursor.getString(cursor.getPosition());
}while(cursor.moveToNext());
}
Intent intent = new Intent(MiSuper2.this, PntArticulo.class);
startActivity(intent);
}
public int doWork() {
while (fileSize <= 1000000) {
fileSize++;
return (int) fileSize;
}
return 100;
}
}
This is the main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:orientation="vertical" >
<ImageView
android:id="#+id/imvLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/presentacion"
android:contentDescription="#string/logo"/>
<ProgressBar
android:id="#+id/progressbar_activity"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="200dp"
android:layout_height="wrap_content" android:layout_marginTop="100dp"/>
</LinearLayout>
Please help
It looks like you are using the doWork() function to take up time so that you're progress bar does something. Even though you wrote a big loop, it still executes very quickly so you don't see your progress bar move. Rather, you want to simulate your Thread doing something computationally intensive by using Thread.sleep() which takes an argument that is the time to sleep in milliseconds.
Try changing your code to this:
new Thread(new Runnable() {
public void run() {
while (mProgressStatus < 100) {
try {
mProgressStatus += doWork();
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.post(new Runnable() {
public void run() {
mProgress.setProgress(mProgressStatus);
}
});
}
runOnUiThread(new Runnable() {
#Override
public void run() {
startActivity(new Intent(MiSuper2.this, Second.class));
}
});
}
}).start();
And...
public int doWork() throws InterruptedException {
Thread.sleep(1000);
return 1;
}
This will increment your progress bar by 1% every second. And finally, the documentation on Thread.sleep(): https://developer.android.com/reference/java/lang/Thread.html#sleep(long)
EDIT: Ramz beat me to this answer, but doesn't provide an explanation of why it's the answer. Hopefully my explanation helps.
EDIT2: I think you edited your questions since I started looking at it a second time. You had some errors in your XML before, but now it is gone. Regardless, your problem is now that you need the call to startActivity() inside your worker thread. Otherwise, the UI thread does not wait for the doWork() function to return and immediately starts the other Activity when your app starts. Sorry, I should have mentioned this before. The code I posted above is updated with this change.
Please try this code SplashScreen.java
package com.cud.point;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ProgressBar;
import android.widget.TextView;
public class SplashScreen extends Activity {
ProgressBar bar;
TextView txt;
int total=0;
boolean isRunning=false;
// handler for the background updating
Handler handler=new Handler() {
#Override
public void handleMessage(Message msg) {
total=total+20;
String perc=String.valueOf(total).toString();
txt.setText(perc+"% completed");
bar.incrementProgressBy(20);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
bar=(ProgressBar)findViewById(R.id.progress);
txt=(TextView)findViewById(R.id.txt);
Handler x = new Handler();
x.postDelayed(new SplashHandler(), 5000);
}
class SplashHandler implements Runnable
{
public void run() {
// TODO Auto-generated method stub
startActivity(new Intent(getApplication(),YourSecound Activity.class));
SplashScreen.this.finish();
}
}
public void onStart() {
super.onStart();
// reset the bar to the default value of 0
bar.setProgress(0);
// create a thread for updating the progress bar
Thread background=new Thread(new Runnable() {
public void run() {
try {
for (int i=0;i<5 && isRunning;i++) {
// wait 100ms between each update
Thread.sleep(1000);
handler.sendMessage(handler.obtainMessage());
}
}
catch (Throwable t) {
} } });
isRunning=true;
// start the background thread
background.start();
}
public void onStop() {
super.onStop();
isRunning=false;
}
}
splash.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="15px" >
<TextView
android:id="#+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Loading......" />
<TextView
android:id="#+id/txt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/imageView1"/>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/splash" />
<ProgressBar
android:id="#+id/progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView1"
android:layout_alignLeft="#+id/imageView1"
android:max="100" />
</RelativeLayout>
this is an example of my project so please make necessary change in xml file
Related
I'm making a splash screen for my app and I'm just testing out putting the primary thread to sleep instead of using a timer. My code is:
package com.example.somu.activityswitcher;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class LauncherActivity extends AppCompatActivity {
public void firstActivity() {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launcher);
TextView countDown = findViewById(R.id.count);
for (int cd=3;cd>0;cd--) {
try {
Thread.sleep(1000);
countDown.setText(Integer.toString(cd));
} catch (Exception e) {
e.printStackTrace();
}
}
firstActivity();
}
}
While the MainActivity loads after 3 seconds, the splash screen (LauncherActivity) is a mere blank screen! What's going on here?!
activity_launcher.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.widget.RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.somu.activityswitcher.LauncherActivity">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:scaleType="fitCenter"
android:scaleX="0.25"
android:scaleY="0.25"
app:srcCompat="#drawable/logo" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/count"
android:layout_centerHorizontal="true"
android:text="Switching in..." />
<TextView
android:id="#+id/count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="70dp"
android:text="3"
android:textColor="#android:color/black"
android:textSize="50sp" />
</android.widget.RelativeLayout>
How do I fix this?!
NOTE: I'm not bothered about any way to fix this.. I want to know why exactly this method won't work, and what is the next best way without explicitly using a timer.
try this,
may be this is useful to you.
public class LauncherActivity extends AppCompatActivity {
private TextView countDown;
int cd;
public void firstActivity() {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launch);
countDown = (TextView) findViewById(R.id.count);
try {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
for (cd = 3; cd > 0; cd--) {
countDown.setText(Integer.toString(cd));
}
firstActivity();
}
}, 3000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
if you want to add countdown than put this insted of handler,
new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
countDown.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
countDown.setText("done!");
firstActivity();
}
}.start();
Try this instead of Thread.sleep(1000);
new CountDownTimer(3000, 1000) {
#Override
public void onTick(long l) {
countDown.setText(Integer.toString(l/1000));
}
#Override
public void onFinish() {
firstActivity();
finish();
}
}.start();
Try to use CountDownTimer to display timer instead of Thread or Handler as below :
onTick() run on UI thread so you can update UI in this method as you trying to show (3,2,1) on countDown TextView.
onFinish called when given timer is complete so you can write your code here after timer completed as you trying show another activity.
new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
countDown.setText(""+ (millisUntilFinished / 1000));
}
public void onFinish() {
firstActivity();
}
}.start();
You are using Thread.sleep(1000); in the main thread which is freezing your UI.
Since the UI thread is frozen, in the meantime, the activity will fail to inflate and render, resulting a mere blank screen.
However, you can use Thread.sleep in a background thread but you can't update UI directly from a background Thread. You can use runOnUiThread to update UI from background thread if you place you countdown code inside a Thread
new Thread(new Runnable(){
public void run(){
//countdown code.
runOnUiThread(new Runnable(){
public void run(){
textView.setText(...
}
});
}
}).start()
try this code.
Intent intent = new Intent(this, WelcomeActivity.class);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
try{
startActivity(intent);
finish();
}
catch (Exception e){
}
}
}, 1000);
Thread.sleep(1000); freezing your UI.
try this
Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
timer = new Timer();
timer.scheduleAtFixedRate(new RemindTask(), 3000, 1000); // delay*/
}
private class RemindTask extends TimerTask {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
i++;
Log.e("title", "" + i);
tv.setText(i + "");
if (i == 3) {
timer.cancel();
firstActivity();
}
}
});
}
}
**I configured a simple single TextView layout (see below after the code) to change the display changing from 10 up to 20. What I see is "20" being displayed. My code is as follows. Want to know why only the last number ("20") is displayed omitting the intermediate ones(10 thru 19))
package com.example.test;
import android.R.string;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
import android.widget.Toast;
public class TestActivity extends Activity {
public TextView mytv;
public Toast mtoast;
#Override
protected void onCreate(Bundle savedInstanceState) {
int i = 10;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
mytv = (TextView) findViewById(R.id.myhw);
mtoast = Toast.makeText(this, String.valueOf(i), Toast.LENGTH_LONG);
while (i++ < 20) {
mtoast.setText(String.valueOf(i));
mtoast.show();
mytv.setText(String.valueOf(i));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.test, menu);
return true;
}
}
The relevant layout is as follows.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".TestActivity" >
<TextView
android:id="#+id/myhw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</RelativeLayout>
because the view is not shown until onResume call and after that the activity is displayed, all you are doing is changing the view content in onCreate method, after onCreate activity goes to onStart and onResume so when onCreate finishes the textView value is 20 and after onResume it sets the value to 20.
for more information look at activity life cycle at :
http://developer.android.com/reference/android/app/Activity.html
You shouldn't sleep the UI thread in the first place.
What you probably want to do is to use another thread, let it sleeps for a couple of seconds and, each time you update the UI, use the UI (main) thread. You can do it in several ways, but the simples probably is using an AsyncTask, as:
public class MyActivity extends Activity {
public TextView mytv;
public Toast mtoast;
private int i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
i = 10;
mytv = (TextView) findViewById(R.id.myhw);
mtoast = Toast.makeText(this, String.valueOf(i), Toast.LENGTH_LONG);
new AsyncTask<Void, String, Void>() {
#Override
protected Void doInBackground(Void... voids) {
while (i < 20) {
publishProgress(String.valueOf(i));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
mtoast.setText(values[0]);
mtoast.show();
mytv.setText(values[0]);
}
}.execute();
}
}
Want to know why only the last number ("20") is displayed omitting the intermediate ones(10 thru 19))
It doesn't work because you sleep the UI Thread.
To make this work, you would have to do it through a Thread, you can use an AsyncTask for this, or a Timer object as i specified below, anyways i recommend the use of AsyncTask.
Once i was doing something simmilar, you could use a Timer object for this.
Using the method: scheduleAtFixedRate(TimerTask task, long delay, long period)
The Docs for this method says
Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay.
It means after the seconds from the second parameter, it will start, using the third parameter as delay for each execution. You will have to cancel it, calling the method:cancel();
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (counter == 20) {
timer.cancel();
counter = 0;
time.setText("Ta-da! I'm Done ");
}else{
counter += 1;
if (time != null)
time.setText(String.valueOf(counter));
}
}
});
}
}, delay, period);
Even further: A Thread.sleep is not the proper way to update a GUI and watch how it changes. The value it will take is the last one. The activity will be blocked until the last is shown.
If you want to see that effect, you should programm a Thread which communicates the main thread every X seconds, and the main thread should listen the Thread to change it.
For example, you could use an AsyncTask and use onProgressUpdate.
Edited with some code:
MainActivity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume(){
super.onResume();
/* Running AsyncTask */
myAsyncTask bkg = new myAsyncTask();
/* I'll pass an integer parameter: milliseconds to wait. */
bkg.execute(3000);
}
private class myAsyncTask extends AsyncTask<Integer, Integer, String> {
#Override
protected void onPreExecute() {
/* TODO: Do BEFORE background process */
Toast.makeText(getApplicationContext(),"I'm going to do a background task!", Toast.LENGTH_SHORT).show();
}
#Override
protected String doInBackground(Integer... parameters) {
/* TODO: What to do in Background */
/* Retrieving parameter passed */
int milliseconds = parameters[0];
try {
Thread.sleep(milliseconds);
publishProgress(milliseconds); /* Will prompt that value */
} catch (InterruptedException e) {
e.printStackTrace();
return "ERROR";
}
int i = 0;
while (i++ < 20) {
try {
Thread.sleep(milliseconds);
publishProgress(i);
} catch (InterruptedException e) {
e.printStackTrace();
return "ERROR";
}
}
return "OK";
}
#Override
protected void onPostExecute(String result) {
/* TODO: After execution of thread */
if(result.equals("OK"))
Toast.makeText(getApplicationContext(),"Correctly Processed", Toast.LENGTH_SHORT).show();
if(result.equals("ERROR"))
Toast.makeText(getApplicationContext(),"Failed", Toast.LENGTH_SHORT).show();
}
#Override
protected void onProgressUpdate(Integer... values) {
/* TODO: Here you can access UI elements as your TextView */
TextView tv = (TextView) findViewById(R.id.tvExample);
tv.setText(values[0]+"");
}
}
}
layout/main_activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.myapplication2.app.MainActivity"
android:id="#+id/whatever">
<TextView
android:text="#string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="#+id/tvExample" />
Use the code (tested on device) provided below:
public class TestActivity extends Activity {
private Handler mHandler;
public TextView mytv;
private int i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toast_showing_acounter);
mytv = (TextView) findViewById(R.id.myhw);
mHandler = new Handler();
i = 10;
scheduleHandler();
}
private void scheduleHandler() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
showCounter();
if (i < 20) {
scheduleHandler();
}
}
}, 5000);
}
private void showCounter() {
Toast.makeText(this, String.valueOf(i), Toast.LENGTH_LONG).show();
mytv.setText(String.valueOf(i));
i++;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.test, menu);
return true;
}
}
I'm getting error with this code. Why huhu
123123123
Thread timer = new Thread()
{
public void run()
{
try
{
sleep(1500);
splash.setImgeResource(R.drawable.dilclogo);
sleep(1500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
finally
{
Intent intent = new Intent(MainActivity.this, MenuScreen.class);
startActivity(intent);
}
}
};
timer.start();
This is because you can NOT access your UI/Main thread directly from any other thread. You can use below methods to access your UI thread though:
Using AsyncTask
Using runOnUiThread()
You can also read this article on threading in android to help you understand this concept better.
put splash.setImgeResource(R.drawable.dilclogo); line into runOnUiThread .
Thread timer = new Thread()
{
public void run()
{
try
{
sleep(2000);
runOnUiThread(new Runnable() {
public void run() {
splash.setImageResource(R.drawable.billboard_image);
}
});
sleep(2000);
runOnUiThread(new Runnable() {
public void run() {
splash.setImageResource(R.drawable.square);
}
});
}
catch (InterruptedException e)
{
e.printStackTrace();
}
finally
{
System.out.println("finally");
}
}
};
timer.start();
You should update ui on the ui thread. Use runonUithread.
runOnUiThread(new Runnable() {
#Override
public void run() {
// set image to imageview here
// ui should be updated on the ui thread.
// you cannot update ui from a background thread
}
});
But i would suggest you to use a handler.
public class Splash extends Activity {
//stopping splash screen starting home activity.
private static final int STOPSPLASH = 0;
//time duration in millisecond for which your splash screen should visible to
//user. here i have taken half second
private static final long SPLASHTIME = 500;
//handler for splash screen
private Handler splashHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case STOPSPLASH:
//Generating and Starting new intent on splash time out
Intent intent = new Intent(Splash.this,
MainActivity.class);
startActivity(intent);
Splash.this.finish();
break;
}
super.handleMessage(msg);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
//Generating message and sending it to splash handle
Message msg = new Message();
msg.what = STOPSPLASH;
splashHandler.sendMessageDelayed(msg, SPLASHTIME);
}
}
splash.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" android:background="#drawable/mydrawable">
// have a imageview and set background to imageview
</RelativeLayout>
Using handlers and postdelayed
public class Splash extends Activity {
private static final int SPLASH_TIME = 2 * 1000;// 3 seconds
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
ImageView iv= (ImageView) findViewById(R.id.imageView1);
iv.setBackgroundResource(R.drawable.afor);
try {
new Handler().postDelayed(new Runnable() {
public void run() {
Intent intent = new Intent(Splash.this,
MainActivity.class);
startActivity(intent);
Splash.this.finish();
}
}, SPLASH_TIME);
} catch(Exception e)
{
e.printStacktrace();
}
}
#Override
public void onBackPressed() {
this.finish();
super.onBackPressed();
}
}
splash.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" android:background="#ffffaa">
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
/>
</RelativeLayout>
You can not use normal threading on android system.
Give you some example on thread on android :D
---> Android Asynctask
Android Developer - Android Asynctask
You can use this for some loading effect on UI in android.
---> runOnUiThread
In your case, I suggest to use this.
You can have more detail here.
Click for detail
USEAGE::
runOnUiThread(new Runnable() {
#Override
public void run() {
// Do you ui update here
}
});
public class vv extends Activity {
int b[] = {R.drawable.a, R.drawable.m, R.drawable.b, R.drawable.j, R.drawable.er, R.drawable.chan, R.drawable.vv};
public ImageView i;
int z = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
i = (ImageView) findViewById(R.id.image);
i.setImageResource(b[0]);
Thread timer = new Thread() {
public void run() {
try {
sleep(2000);
for (z = 0; z < b.length + 2; z++) {
if (z < b.length) {
sleep(2000);
runOnUiThread(new Runnable() {
public void run() {
i.setImageResource(b[z]);
}
});
} else {
z = 0;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("finally");
}
}
};
timer.start();
}
}
Perhaps consider using
AsyncTask.execute(new Runnable {
public void run() {
splash.setImageResource(R.drawable.square);
}
});
I am trying to display a progress bar using threading .. I accept that I do not have that much concept of threading.
Here is the code
public class Progress extends Activity {
static String[] display;
private static final int Progress = 0;
private ProgressBar mProgress;
private int mProgressStatus = 0;
private Handler mHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.progress);
mProgress = (ProgressBar) findViewById(R.id.progressBar);
// Start lengthy operation in a background thread
new Thread(new Runnable() {
public void run() {
while (mProgressStatus < 100) {
mProgressStatus = doWork();
// Update the progress bar
mHandler.post(new Runnable() {
public void run() {
mProgress.setProgress(mProgressStatus);
}
});
}
}
private int doWork() {
display = new Logic().finaldata();
// TODO Auto-generated method stub
return 100;
}
}).start();
}
}
On running, the logcat message is
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
What is the mistake that I am doing here?
So your problem will be elsewhere. I tried your example with Handler and it works for me.
package com.sajmon.threadsDemo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ProgressBar;
import android.widget.TextView;
public class ThreadsDemoActivity extends Activity {
ProgressBar bar;
TextView label;
Handler handler = new Handler();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bar = (ProgressBar) findViewById(R.id.progBar);
new Thread(new Runnable() {
int i = 0;
int progressStatus = 0;
public void run() {
while (progressStatus < 100) {
progressStatus += doWork();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Update the progress bar
handler.post(new Runnable() {
public void run() {
bar.setProgress(progressStatus);
i++;
}
});
}
}
private int doWork() {
return i * 3;
}
}).start();
}
}
And XML:
<ProgressBar
android:id="#+id/progBar" style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
So look at this and edit your code similar with this.
Find the below example code for progress bar update using threads
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
public class ThreadDemo1ProgressBar extends Activity
{
ProgressBar bar;
TextView msgWorking;
boolean isRunning = false;
Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
bar.incrementProgressBy(5);
if (bar.getProgress() == bar.getMax()) {
msgWorking.setText("Done");
bar.setVisibility(View.INVISIBLE);
} else {
msgWorking.setText("Working..." +
bar.getProgress());
}
}// handleMessage
};
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
bar = (ProgressBar) findViewById(R.id.progress);
bar.setMax(100);
msgWorking = (TextView) findViewById(R.id.TextView01);
}
public void onStart() {
super.onStart();
bar.setProgress(0);
Thread background = new Thread(new Runnable() {
public void run() {
try
{
for (int i = 0; i < 20 && isRunning; i++) {
Thread.sleep(1000);
handler.sendMessage(handler.obtainMessage());
}
}
catch(Throwable t) {
// just end the background thread
}
}
});
isRunning = true;
background.start();
}// onStart
public void onStop() {
super.onStop();
isRunning = false;
}
}// ThreadDemo1ProgressBar
The about example updating the progress bar for every 5 seconds.
I actually just create a thread instance once and it works anyway. This code was written in the Startup Activity. All you need to do is call showSpinner1() method to show/hide the spinner.
Ensure to do this
getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS); in your onCreate() method and use this code for toggling the spinner ON and OFF.
// Spinner related code - The thread is created just once and is used multiple times (works!!)
boolean toShow = false;
Thread spinner1Thread = new Thread("Show/Hide Spinner Thread") {
#Override
public void run() {
setProgressBarIndeterminateVisibility(toShow);
}
};
/**
* Shows and hides the spinner
* #param pShow
*/
public void showSpinner1(boolean pShow) {
toShow = pShow;
runOnUiThread(spinner1Thread);
}
I have this code for the xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="15px"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Loading..."
/>
<ProgressBar android:id="#+id/progressBar"
android:paddingTop="10px"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="100" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/txt"
/>
</LinearLayout>
Then for the class :
public class Loading extends Activity {
ProgressBar bar;
TextView txt;
int total=0;
boolean isRunning=false;
// handler for the background updating
Handler handler=new Handler() {
#Override
public void handleMessage(Message msg) {
total=total+5;
String perc=String.valueOf(total).toString();
txt.setText(perc+"% completed");
bar.incrementProgressBy(5);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.loading_bar);
bar=(ProgressBar)findViewById(R.id.progressBar);
txt=(TextView)findViewById(R.id.txt);
}
public void onStart() {
super.onStart();
// reset the bar to the default value of 0
bar.setProgress(0);
// create a thread for updating the progress bar
Thread background=new Thread(new Runnable() {
public void run() {
try {
for (int i=0;i<20 && isRunning;i++) {
// wait 1000ms between each update
Thread.sleep(1000);
handler.sendMessage(handler.obtainMessage());
}
}
catch (Throwable t) {
}
}
});
isRunning=true;
// start the background thread
background.start();
}
public void onStop() {
super.onStop();
isRunning=false;
}
}
And with this I call it on another activity:
public void onClick (View v)
{
switch (v.getId())
{
case R.id.buttonNext3:
Intent Loading = new Intent(this, Loading.class);
startActivity(Loading);
getContent();
Call();
db.generation();
Intent Next3 = new Intent(this, FoodPlanning.class);
startActivity(Next3);
break;
}
}
But it is not work on mine, it just show blackscreen but it still on progress .... I want the loading bar appear when I click the button and the process still on progress. any idea? Thx u
As suggested by Adil, AsyncTask is the preferred method to run background tasks with easy options to run certain commands on the UI thread, while pushing the rest to the background. See this example from the SDK (http://developer.android.com/reference/android/os/AsyncTask.html):
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
Note the "onProgressUpdate" method as well as the doInBackground.