I am working on a homework project that requires to have a textview counter along with an existing progress bar. I added the textview code to java file and main.xml. When I run it in the emulator I get "The application xxx has stopped unexpectedly" message. I have not been able to figure out the cause. Here is my code:
(Code indentation is not entirely proper. I will strive to make it so)
Source file:
package com.mypackage;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MyButtonActivity extends Activity {
static final int PROGRESS_DIALOG = 0;
Button button;
ProgressThread progressThread;
ProgressDialog progressDialog;
TextView Int;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Int = (TextView)findViewById(R.id.Int);
// Setup the button that starts the progress dialog
button = (Button) findViewById(R.id.myButton);
button.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
// Show dialog managed by this activity
showDialog(PROGRESS_DIALOG);
}
});
}
// Callback for creating dialogs that are managed (saved and restored)
// for you by the activity.
protected Dialog onCreateDialog(int id) {
switch(id) {
case PROGRESS_DIALOG:
progressDialog = new ProgressDialog(MyButtonActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading...");
// Create and start the handler
progressThread = new ProgressThread(handler);
progressThread.start();
return progressDialog;
default:
return null;
}
}
// Define the Handler that receives messages from the thread and update
// the progress
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
int total = msg.getData().getInt("total");
progressDialog.setProgress(total);
Int.setText(String.valueOf(total));
if (total >= 100){
dismissDialog(PROGRESS_DIALOG);
progressThread.setState(ProgressThread.STATE_DONE);
}
}
};
/** Nested class that performs progress calculations (counting) */
private class ProgressThread extends Thread {
Handler mHandler;
final static int STATE_DONE = 0;
final static int STATE_RUNNING = 1;
int mState;
int total;
ProgressThread(Handler h) {
mHandler = h;
}
public void run() {
mState = STATE_RUNNING;
total = 0;
while (mState == STATE_RUNNING) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Log.e("ERROR", "Thread Interrupted");
}
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
mHandler.sendMessage(msg);
total++;
}
}
/* sets the current state for the thread,
* used to stop the thread */
public void setState(int state) {
mState = state;
}
}
I only added a few lines to existing code (including a textview to main.xml). So is it more involved than simply adding textview code to implement the textview counter? Given that it is one of first projects in my intro level course, I think simply adding a textview should satisfy the requirement. Please enlighten. Thanks!
I tested your code and it worked for me! Did you try to:
Under Eclipse bar Project->Clean Project
Right click on your project Android Tools->Fix Project Properties
Related
I'm working on getting a better handle on AsyncTask and am trying to create controls dynamically with asyncTask's onPostExecute().
The code I have below does work and it creates controls, but is there a way to loop this, but delay it so that variable I is incremented after the asynctask completes?
I've read through using the get() method, but I can't seem to make it work.
Can anyone advise how to either wait till a background task is complete or some other way to dynamically create controls based on a variable number?
package com.example.dynamicallycreatecontrols;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.Menu;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
public class MainActivity extends Activity {
Integer i = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
while (i < 5) {
new createControl().execute(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.main, menu);
return true;
}
//asynctask
public class createControl extends AsyncTask<Integer, Void, Button> {
Button btn = new Button(MainActivity.this);
LinearLayout ll = (LinearLayout) findViewById (R.id.llMain);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
protected void onPreExecute(Integer i) {
// nothing right now
}
#Override
protected Button doInBackground(Integer... arg0) {
// TODO Auto-generated method stub
// do the calculation
return null;
}
protected void onPostExecute(Button v) {
// build the controls here
btn.setText("Play" + i);
ll.addView(btn, lp);
SystemClock.sleep(1000);
}
}
}
I'm new to android development and java so i'm not sure if I'm just misunderstanding a concept of get() or if there is a better way to do this all together.
Thanks for any time allocated in assistance.
-nick
When doInBackground() done I move to onPostExecute(). I don't need any delays there. When I call task.execute(/**/) actually I invoke doInBackground() async task and I don't care when it finish but I know that I have callback onPostExecute() and I wait and update my main Thread from there.
To make it clearer lets say you have application where user wants to register to server and update GUI led to green color. User presses on button and calls method registerClient()
This method runs:
private void registerClient(){
...
dialog = ProgressDialog.show(LoginActivity.this, "", "Connecting. Please wait...", true);
HeavyTask task = new HeavyTask();
task.execute(user, password, domain);
}
So what we have in HeavyTask:
private class HeavyTask extends AsyncTask<String, Void, Void> {
private String username = "";
private String domain = "";
private String password = "";
// run async task
protected Void doInBackground(String... args) {
username = args[0];
password = args[1];
domain = args[2];
registerClientToServer(username, password, domain, null);
return null;
}
protected void onPostExecute(Void results) {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
updateGUI(username, domain);
}
}, 500);
}
}
Why not create an object and instantiate it? You can control if the object exists or if it already finished what he had to do.
Example:
public class MainActivity extends Activity {
private createControl cc = null;
Integer i = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
while (i < 5) {
if (cc == null){
cc = new createControl();
cc.execute(i);
i++;
}
}
}
...
}
Then in onPostExecute just add cc = null;
I have one button in the main.xml which will link to another xml which include information from server. I include progress bar to avoid the blank screen while the system is loading the information. i already done the code as below but it's still not the things i wanted. the code below will "WAIT" for 1000 ms then only will execute the next code. how can i modify it so that the loading "WAIT TIME" will depends on the internet speed, if internet connection is slow, then the progress-bar-screen will show longer.
package com.android.myApps;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;
public class MainScr extends Activity {
private final int WAIT_TIME = 1000;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.MainScr);
}
public void onClickCategory(View view)
{
findViewById(R.id.mainSpinner1).setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
Intent mainIntent = new Intent(MainScr.this, Category.class);
MainScr.this.startActivity(mainIntent);
MainScr.this.finish();
}
}, WAIT_TIME);
}
}
The mistake you are doing here is you are dumping specific time into your code
You never know how much it will take to get response.
You should follow following approach
Step 1 Show progress dialog on screen
Step 2 Let download take its own time.But it should be done in new thread
Step 3 Once download is complete it will raise message that task is done,now remove that
progress dialog and proceed.
I am pasting sample code here.Hope it will help you.
package com.android.myApps;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class MainScr extends Activity
{
private Handler handler;
private ProgressDialog progress;
private Context context;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = AncActivity.this;
progress = new ProgressDialog(this);
progress.setTitle("Please Wait!!");
progress.setMessage("Wait!!");
progress.setCancelable(false);
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
progress.dismiss();
Intent mainIntent = new Intent(context, Category.class);
startActivity(mainIntent);
super.handleMessage(msg);
}
};
progress.show();
new Thread()
{
public void run()
{
// Write Your Downloading logic here
// at the end write this.
handler.sendEmptyMessage(0);
}
}.start();
}
}
Did you try Asyntask? Your doing process will be update in UI.
public final class HttpTask
extends
AsyncTask<String/* Param */, Boolean /* Progress */, String /* Result */> {
private HttpClient mHc = new DefaultHttpClient();
#Override
protected String doInBackground(String... params) {
publishProgress(true);
// Do the usual httpclient thing to get the result
return result;
}
#Override
protected void onProgressUpdate(Boolean... progress) {
// line below coupled with
// getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS)
// before setContentView
// will show the wait animation on the top-right corner
MyActivity.this.setProgressBarIndeterminateVisibility(progress[0]);
}
#Override
protected void onPostExecute(String result) {
publishProgress(false);
// Do something with result in your activity
}
}
package com.aviyehuda.test.multithreading;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MultithreadingTest extends Activity {
Button btn;
private Handler myHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.Button01);
}
public void buttonClicked(View v) {
myHandler = new Handler();
MyThread mThread = new MyThread();
mThread.start();
}
class MyThread extends Thread {
#Override
public void run() {
for (int i = 0; i < 30; i++) {
myHandler.post(new NewThreaad(i));
}
}
}
class NewThreaad implements Runnable{
int i;
public NewThreaad(int n) {
i=n;
}
#Override
public void run() {
((TextView) findViewById(R.id.TextView01)).setText("Hello:"+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I have code mentioned above but getting result Hello29 on TextView but i want Hello1,Hello2,hello3.................Hello29 one by one automatically
Please give me hint what I am doing wrong
A couple of things.
First, after changing the text, you should call invalidate on the TextView to force a refresh.
Second, to do operation on the UI, you should run that in the UI thread. Use runOnUiThread
Well, the main problem is that you're not appending you are overwriting. Instead of
((TextView) findViewById(R.id.TextView01)).setText("Hello:"+i);
do
TextView tv = ((TextView) findViewById(R.id.TextView01));
String text = tv.getText().toString();
tv.setText(text + " Hello:" + i);
You need to move the 500 ms delay to your for-loop, between posting of messages. I think you're expecting the messages to execute sequentially one after the other, but they don't, which is the reason you just see the result of the last one.
I am experiencing a problem I have following code:
public void onCreate(Bundle savedInstanceState) {
MyDialog = ProgressDialog.show(this, "Nalagam kanale" , "Prosimo počakaj ... ", true);
MyDialog.show();
... }
Which should actually start he dialog... But the problem is that dialog is shown when everything is loaded...
How can I do solve that?
Actual code
package com.TVSpored;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
public class Currently extends Activity{
static final int PROGRESS_DIALOG = 0;
private ArrayList<CurrentlyItem> currentItems;
private CurrentAdapter aa;
private ListView currentListView;
private JSONArray CurrentShows;
private Communicator CommunicatorEPG;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.layout_currently);
CommunicatorEPG = new Communicator();
currentItems = new ArrayList<CurrentlyItem>();
if(currentItems == null)
int resID = R.layout.current_item;
aa = new CurrentAdapter(this, resID, currentItems);
currentListView = (ListView)findViewById(R.id.currentListView);
try {
currentListView.setAdapter(aa);
} catch (Exception e) {
Log.d(" * Napaka", e.toString());
}
try {
populateCurrent();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void populateCurrent() throws JSONException
{
CurrentShows = CommunicatorEPG.getCurrentShows(0);
for (int i = 0; i < CurrentShows.length(); i++)
{
JSONObject jsonObject = CurrentShows.getJSONObject(i);
String start = jsonObject.getString("1");
Integer duration = jsonObject.getInt("2");
String title = jsonObject.getString("3");
String epg_channel = jsonObject.getString("4");
String channel_name = jsonObject.getString("5");
CurrentlyItem newItem = new CurrentlyItem(1, 2, 3, 4, 5);
currentItems.add(i, newItem);
}
}
}
This is actual code... I would like to do populateCurrent(); in AsyncTask and meanwhile I would like a loading screen to be shown... Have been trying for few hours now but no actual success... I have successfully shown loading screen and wen trough JSONArray, but couldn't update listview...
Thanks for support!
Expected behaviour...
Show a dialog is a typical task of UI thread, but until you complete the onCreate method, the UI thread s not free to execute the dialog creation...
Two solution: create a dialog in a separate thread or execute your long task in a separate thread.
Some highlights here:
http://developer.android.com/guide/topics/ui/dialogs.html
You could wait to set the content of the activity until the you're finished with the progress dialog.
Update:
This would run your command in async-task:
new AsyncTask<Void, Void, Void> {
protected Long doInBackground(Void... voids) {
populateCurrent();
}
}.execute()
However, then you probably have to make sure to update the list in the GUI thread again and in some way tell the adapter that the list have been updated (since you've given that list to the adapter):
runOnUiThread(new Runnable() {
public void run() {
currentItems.add(i, newItem);
aa.notifyDataSetChanged();
}
}
It is probably best to create a new list entirely and set the view to view that.
I have problem that how to change text inside the progressdialog (basically having STYLE_HORIZONTAL as in figure) (Using Android 1.6)
to text shown in figure.
Please help out in this case.
My code about the progressdialog refers like this:-
mProgressDialog = new ProgressDialog(PDFActivity.this);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setTitle(R.string.msgDownloadingWait);
mProgressDialog.setMessage(getResources().getString(
R.string.msgDownloading));
// User is not allowed to cancel the download operation.
mProgressDialog.setCancelable(false);
mProgressDialog.setMax(serverFileCount);
mProgressDialog.show();
Thanks in advance.
I got the answer related to this stuff some days back(but updating it today as got some free time).
Here the code that I have used for making this stuff best.I achieved above thing by Custom Dialog.Firstly here the code of activity from which I called the class of Custom Dialog.
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.TextView;
public class ProgressThread extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyDialog dialog = new MyDialog(this);
dialog.show();
}
}
Now the code related to the Custom Dialog. Here I have used ProgressBar & TextViews in CustomDialog & made calculations on basis on download which in turn updates TextViews.The example used here updates the textviews & progressbar in dummy manner.You change that as per your need.
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.os.Message;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MyDialog extends Dialog {
public static final int STATUS_UPDATE = 101;
public static final int STATUS_COMPLETE = 100;
ProgressBar progressBar;
TextView textView;
TextView percent;
int increment;
int progress;
public MyDialog(Context context) {
super(context);
setContentView(R.layout.progressbar);
setDialog();
}
private void setDialog() {
setTitle("Downloading Files....");
textView = (TextView) findViewById(R.id.textProgress);
progressBar = (ProgressBar) findViewById(R.id.progress_horizontal);
percent = (TextView) findViewById(R.id.textPercentage);
percent.setTextColor(Color.WHITE);
textView.setTextColor(Color.WHITE);
progressBar.setProgressDrawable(getContext().getResources()
.getDrawable(R.drawable.my_progress));
progressBar.setIndeterminate(false);
// set the maximum value
progressBar.setMax(1315);
launcherThread();
}
private void launcherThread() {
LoaderThread loaderThread = new LoaderThread();
loaderThread.start();
LauncherThread launcherThread = new LauncherThread();
launcherThread.start();
}
private class LoaderThread extends Thread {
#Override
public void run() {
try {
while (progressBar.getProgress() < progressBar.getMax()) {
// wait 500ms between each update
Thread.sleep(100);
increment++;
// active the update handler
progressHandler.sendEmptyMessage(STATUS_UPDATE);
}
progressHandler.sendEmptyMessage(STATUS_COMPLETE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// handler for the background updating
Handler progressHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case STATUS_UPDATE:
progressBar.setProgress(increment);
float value = increment / 1315F;
percent.setText(" " + ((int) (value * 100)) + "%");
System.out.println(value * 100);
textView.setText(String.valueOf(progressBar.getProgress())
.concat(" / " + progressBar.getMax()));
break;
case STATUS_COMPLETE:
dismiss();
}
}
};
private class LauncherThread extends Thread {
#Override
public void run() {
progressHandler.sendMessage(progressHandler.obtainMessage());
progressHandler.sendEmptyMessage(0);
}
}
}