I m developing a quiz based app and in this m trying to jump on some method after some delay time but unfortunately m getting some Run time Error..
Here's that code..
new Timer().schedule(new TimerTask() {
#Override
public void run()
{
resetcolor();
nextpage();
rg.clearCheck();
showdata();
}
}, 6000);
And here's my Log cat Error..
09-12 12:11:06.775: W/dalvikvm(489): threadid=7: thread exiting with uncaught exception (group=0x4001d800)
09-12 12:11:06.789: E/AndroidRuntime(489): FATAL EXCEPTION: Timer-0
09-12 12:11:06.789: E/AndroidRuntime(489): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
09-12 12:11:06.789: E/AndroidRuntime(489): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.view.View.invalidate(View.java:5115)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.widget.TextView.invalidateDrawable(TextView.java:3796)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:300)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.graphics.drawable.DrawableContainer.selectDrawable(DrawableContainer.java:227)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.graphics.drawable.StateListDrawable.onStateChange(StateListDrawable.java:97)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.graphics.drawable.Drawable.setState(Drawable.java:400)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.widget.CompoundButton.drawableStateChanged(CompoundButton.java:271)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.view.View.refreshDrawableState(View.java:7248)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.widget.CompoundButton.setChecked(CompoundButton.java:115)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.widget.RadioGroup.setCheckedStateForView(RadioGroup.java:179)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.widget.RadioGroup.check(RadioGroup.java:159)
09-12 12:11:06.789: E/AndroidRuntime(489): at android.widget.RadioGroup.clearCheck(RadioGroup.java:205)
09-12 12:11:06.789: E/AndroidRuntime(489): at com.example.quizapp.Firstques$1$1.run(Firstques.java:234)
09-12 12:11:06.789: E/AndroidRuntime(489): at java.util.Timer$TimerImpl.run(Timer.java:289)
Rewrite your code as follows:
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(6000);
runOnUiThread(new Runnable() {
#Override
public void run() {
resetcolor();
nextpage();
rg.clearCheck();
showdata();
}
});
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}).start();
Your problem is that you cannot touch UI elements from background thread. The code above executes the UI changes in the main thread (also known as "UI thread").
TimerTask runs on a different thread. Ui should be updated or accessed on ui thread. So use runOnUiThread
Inside the timertask run method
new Timer().schedule(new TimerTask() {
#Override
public void run()
{
runOnUiThread(new Runnable() {
#Override
public void run() {
resetcolor();
nextpage();
rg.clearCheck();
showdata();
}
});
}
}, 6000);
Or use a Handler
Handler m_handler;
Runnable m_handlerTask ;
handler= new Handler()
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something
resetcolor();
nextpage();
rg.clearCheck();
showdata()
m_handler.postDelayed(m_handlerTask, 6000);
}
};
m_handlerTask.run();
To stop the handlerm_handler.removeCallbacks(m_handlerTask)
Related
I would like use JSOUP in two Activity, but in both I have same code.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button titlebutton = (Button) findViewById(R.id.button1);
titlebutton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// Execute Title AsyncTask
new AsyncTest().execute();
}
});
}
private class AsyncTest extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
Connection.Response response = null;
try {
response = Jsoup.connect("http://example.com")
.data("param1", "aaaa")
.data("param2", "bbbb")
.data("param3", "ccc")
.data("param4", "dd")
.execute();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
and:
public class Second extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
get();
}
public Connection.Response get()
{
Connection.Response response = null;
try {
response = Jsoup.connect("http://example.com")
.data("param1", "aaaa")
.data("param2", "bbbb")
.data("param3", "ccc")
.data("param4", "dd")
.execute();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
}
This is only example - I use in Second Activity a lot of operation with JSOUP, so I would like have function get in this class and import it into MainActivity.
I try in MainActivity:
private class AsyncTest extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
Connection.Response response = null;
response = new Second().get();
return null;
}
}
but this return errors:
08-25 21:18:00.164: W/dalvikvm(1552): threadid=11: thread exiting with uncaught exception (group=0x409961f8)
08-25 21:18:00.174: E/AndroidRuntime(1552): FATAL EXCEPTION: AsyncTask #1
08-25 21:18:00.174: E/AndroidRuntime(1552): java.lang.RuntimeException: An error occured while executing doInBackground()
08-25 21:18:00.174: E/AndroidRuntime(1552): at android.os.AsyncTask$3.done(AsyncTask.java:278)
08-25 21:18:00.174: E/AndroidRuntime(1552): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
08-25 21:18:00.174: E/AndroidRuntime(1552): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
08-25 21:18:00.174: E/AndroidRuntime(1552): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
08-25 21:18:00.174: E/AndroidRuntime(1552): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-25 21:18:00.174: E/AndroidRuntime(1552): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
08-25 21:18:00.174: E/AndroidRuntime(1552): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
08-25 21:18:00.174: E/AndroidRuntime(1552): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
08-25 21:18:00.174: E/AndroidRuntime(1552): at java.lang.Thread.run(Thread.java:856)
08-25 21:18:00.174: E/AndroidRuntime(1552): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
08-25 21:18:00.174: E/AndroidRuntime(1552): at android.os.Handler.<init>(Handler.java:121)
08-25 21:18:00.174: E/AndroidRuntime(1552): at android.app.Activity.<init>(Activity.java:735)
08-25 21:18:00.174: E/AndroidRuntime(1552): at com.example.js.Second.<init>(Second.java:11)
08-25 21:18:00.174: E/AndroidRuntime(1552): at com.example.js.MainActivity$AsyncTest.doInBackground(MainActivity.java:35)
08-25 21:18:00.174: E/AndroidRuntime(1552): at com.example.js.MainActivity$AsyncTest.doInBackground(MainActivity.java:1)
08-25 21:18:00.174: E/AndroidRuntime(1552): at android.os.AsyncTask$2.call(AsyncTask.java:264)
08-25 21:18:00.174: E/AndroidRuntime(1552): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-25 21:18:00.174: E/AndroidRuntime(1552): ... 5 more
How is the best way to non-repeat code in my example?
Make your AsyncTask public and move it to a separate class (file):
AsyncTest.java:
public class AsyncTest extends AsyncTask<Void, Void, Void> {
...
}
Then in your activities call:
new AsyncTest().execute();
I have been struck with Iterator for past few hours.
While I execute Iterator, am getting NoSuchElementException
Code
new Thread() {
#Override
public void run() {
System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
final HashSet<String> mList = new HashSet<String>();
for (SomeList sList : refList) { // <-- 72 Items
if (sList.isTrue()) {
mList.add(sList.getName());
}
}
System.out.println("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww");
System.out.println("sList " + sList.size()); // <-- 3 Items
final Iterator<String> iterator = mList.iterator();
while (iterator.hasNext()) { // Check if has next element
runOnUiThread(new Runnable() {
#Override
public void run() {
System.out.println("zzzzzzzzzzzzzz");
System.out.println("\n-------------------- " + (String) iterator.next()); //move to next element
}
});
}
}
}.start();
Logcat
D/dalvikvm(25527): start new thread
D/dalvikvm(25527): threadid=13: notify debugger
D/dalvikvm(25527): threadid=13 (Thread-4167): calling run()
I/System.out(25527): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
I/System.out(25527): wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
I/System.out(25527): mList 3 <-- Size of List
I/System.out(25527): yyyyyyyyyyyyyyyyyyyyyy
I/System.out(25527): yyyyyyyyyyyyyyyyyyyyyy
// Prints around 80 times removed for better readability
I/System.out(25527): yyyyyyyyyyyyyyyyyyyyyy
I/System.out(25527): yyyyyyyyyyyyyyyyyyyyyy
I/System.out(25527): zzzzzzzzzzzzzz
I/System.out(25527): -------------------- abc <-- data 1
I/System.out(25527): yyyyyyyyyyyyyyyyyyyyyy
I/System.out(25527): zzzzzzzzzzzzzz
I/System.out(25527): -------------------- efg <-- data 2
I/System.out(25527): zzzzzzzzzzzzzz
I/System.out(25527): -------------------- hij <-- data 3
I/System.out(25527): zzzzzzzzzzzzzz
D/AndroidRuntime(25527): Shutting down VM
W/dalvikvm(25527): threadid=1: thread exiting with uncaught exception (group=0x41c5c9a8)
D/dalvikvm(25527): threadid=13: exiting
D/dalvikvm(25527): threadid=13: bye!
E/AndroidRuntime(25527): FATAL EXCEPTION: main
E/AndroidRuntime(25527): java.util.NoSuchElementException
E/AndroidRuntime(25527): at java.util.HashMap$HashIterator.nextEntry(HashMap.java:794)
E/AndroidRuntime(25527): at java.util.HashMap$KeyIterator.next(HashMap.java:819)
E/AndroidRuntime(25527): at xxx.xxx.xxxxxx.models.YYYYY$1$1.run(YYYYY.java:62) <-- Here is the exception.
E/AndroidRuntime(25527): at android.os.Handler.handleCallback(Handler.java:725)
E/AndroidRuntime(25527): at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(25527): at android.os.Looper.loop(Looper.java:153)
E/AndroidRuntime(25527): at android.app.ActivityThread.main(ActivityThread.java:5299)
E/AndroidRuntime(25527): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(25527): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(25527): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
E/AndroidRuntime(25527): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
E/AndroidRuntime(25527): at dalvik.system.NativeStart.main(Native Method)
Line 62 in my code is
System.out.println("\n-------------------- " + (String) iterator.next());
Before posting this question I searched for NoSuchElementException, Iterator, tried most of the results but did not succeed.
There is a concurrency issue here:
while (iterator.hasNext()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
(String) iterator.next();
}
});
}
Because hasNext and next are not called on the same thread, you cannot be guaranteed that there will actually be a next when you call next().
The loop will run several times without the iterator being advanced, resulting in more creation of Runnables than items in the iterator, which in turn results in next being called more times than should be.
You can solve it using the following:
while (iterator.hasNext()) {
final String nextValue = (String) iterator.next();
runOnUiThread(new Runnable() {
#Override
public void run() {
// Do stuff with nextValue
}
});
}
which calls hasNext and next in the same thread, making sure each hasNext is immediately matched by a call to next
i am trying to implement Runnable and run the Run() method when a thread is started. but when i run the program it crashed.
MainActivity
public class MainActivity extends Activity implements Runnable{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread t1;
t1=new Thread(this);
t1.start();
}
public void run() {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "display something",
Toast.LENGTH_LONG).show();
}
i tried changing it to t1=new Thread(new MainActivity());(app crashed) or just t1=new Thread(); never crash but no output.
how do i implement a Runnable Run when a thread is started? i search all over the place but could not find an answer. i need to include this function in my main project code too. but i create a separate testing project just to get how this works so i can add it in my main project code myself. at my main project it crashed at this point too. it never reached the Run method.
after it crashed, this is the LogCat
01-21 13:03:06.460: W/dalvikvm(879): threadid=11: thread exiting with uncaught exception (group=0xb3a6fb90)
01-21 13:03:06.460: E/AndroidRuntime(879): FATAL EXCEPTION: Thread-51
01-21 13:03:06.460: E/AndroidRuntime(879): Process: com.example.testthreadrun, PID: 879
01-21 13:03:06.460: E/AndroidRuntime(879): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
01-21 13:03:06.460: E/AndroidRuntime(879): at android.os.Handler.<init>(Handler.java:200)
01-21 13:03:06.460: E/AndroidRuntime(879): at android.os.Handler.<init>(Handler.java:114)
01-21 13:03:06.460: E/AndroidRuntime(879): at android.widget.Toast$TN.<init>(Toast.java:327)
01-21 13:03:06.460: E/AndroidRuntime(879): at android.widget.Toast.<init>(Toast.java:92)
01-21 13:03:06.460: E/AndroidRuntime(879): at android.widget.Toast.makeText(Toast.java:241)
01-21 13:03:06.460: E/AndroidRuntime(879): at com.example.testthreadrun.MainActivity.run(MainActivity.java:29)
01-21 13:03:06.460: E/AndroidRuntime(879): at java.lang.Thread.run(Thread.java:841)
01-21 13:03:07.010: I/Choreographer(879): Skipped 126 frames! The application may be doing too much work on its main thread.
01-21 13:03:07.970: I/Choreographer(879): Skipped 165 frames! The application may be doing too much work on its main thread.
01-21 13:03:08.840: D/gralloc_goldfish(879): Emulator without GPU emulation detected.
01-21 13:03:10.770: I/Choreographer(879): Skipped 31 frames! The application may be doing too much work on its main thread.
01-21 13:03:26.670: I/Process(879): Sending signal. PID: 879 SIG: 9
Since you are trying to update the UI, you need to do it on the UI Thread. You should use something like runOnUiThread() or AsyncTask.
runOnUiThread(new Runnable()
{
#Override
public void run()
{
Toast.makeText(MainActivity.this, "display something",
Toast.LENGTH_LONG).show();
}
});
or
Example of AsyncTask
AsyncTask Docs
You can't update ui from a background thread. You can update ui from ui thread only.
You can use runOnUiThread. But to just display a toast why do you require a thread?.
http://developer.android.com/guide/components/processes-and-threads.html
You cannot do UI changes (like a toast) on a thread that is not the UI thread. Use this instead:
public void run() {
MainActivity.this.runOnUiThread(new Runnable(){
#Override
public void run(){
Toast.makeText(MainActivity.this, "display something",
Toast.LENGTH_LONG).show();
}
});
}
However, why are you creating a whole separate thread to show a toast? You're better off just putting Toast.makeText(MainActivity.this, "display something",
Toast.LENGTH_LONG).show(); in your onCreate method.
I am reading the .OBJ file which is in asset folder. But I am getting exception while reading the file. Even I debug the project on eclipse but I could find the reason for this.
Please help me
Thanks in advance.
/**
* Load Object Asynchronous.
* #author Ajay
*/
private class ObjLoaderAsync extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
try {
progressDialog = new ProgressDialog(localContext);
progressDialog.setTitle(localContext
.getString(R.string.app_name));
progressDialog.setMessage(localContext
.getString(R.string.please_wait));
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setCancelable(true);
progressDialog.show();
} catch (Exception e) {
}
}
#Override
protected Void doInBackground(Void... arg0) {
try {
mr[getCurrentPosition()] = new ModelRenderer(localContext,
localContext.getAssets().open(RendererView.objName));
} catch (java.io.IOException e) {
Log.v("DemoRendererView", "loading model: " + e);
}
return null;
}
#Override
protected void onPostExecute(Void param) {
try {
progressDialog.cancel();
} catch (Exception e) {
}
}
}
public ModelRenderer(Context paramContext, InputStream localFileInputStream) throws FileNotFoundException {
ModelStaticClassTransfer.value = -777.0F;
while (true) {
try {
i = localFileInputStream.read();
if (i != -1)
continue;
localFileInputStream.close();
if ((char) i == 'v') {
i = localFileInputStream.read();
if ((char) i != ' ')
continue;
this.verticeCounter = (1 + this.verticeCounter);
continue;
}
if ((char) i == 'f') {
i = localFileInputStream.read();
if ((char) i != ' ')
continue;
this.indexCounter = (1 + this.indexCounter);
continue;
}
int j = localFileInputStream.read();
i = j;
} catch (IOException localIOException) {
localIOException.printStackTrace();
return;
}
}
}
Error Trace
09-12 12:54:57.516: E/AndroidRuntime(29949): FATAL EXCEPTION: AsyncTask #2
09-12 12:54:57.516: E/AndroidRuntime(29949): java.lang.RuntimeException: An error occured while executing doInBackground()
09-12 12:54:57.516: E/AndroidRuntime(29949): at android.os.AsyncTask$3.done(AsyncTask.java:278)
09-12 12:54:57.516: E/AndroidRuntime(29949): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
09-12 12:54:57.516: E/AndroidRuntime(29949): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
09-12 12:54:57.516: E/AndroidRuntime(29949): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
09-12 12:54:57.516: E/AndroidRuntime(29949): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
09-12 12:54:57.516: E/AndroidRuntime(29949): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
09-12 12:54:57.516: E/AndroidRuntime(29949): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
09-12 12:54:57.516: E/AndroidRuntime(29949): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
09-12 12:54:57.516: E/AndroidRuntime(29949): at java.lang.Thread.run(Thread.java:856)
09-12 12:54:57.516: E/AndroidRuntime(29949): Caused by: java.lang.NullPointerException: asset
09-12 12:54:57.516: E/AndroidRuntime(29949): at android.content.res.AssetManager.readAssetChar(Native Method)
09-12 12:54:57.516: E/AndroidRuntime(29949): at android.content.res.AssetManager.access$200(AssetManager.java:35)
09-12 12:54:57.516: E/AndroidRuntime(29949): at android.content.res.AssetManager$AssetInputStream.read(AssetManager.java:548)
09-12 12:54:57.516: E/AndroidRuntime(29949): at com.amplimesh.models.ModelRenderer.<init>(ModelRenderer.java:64)
09-12 12:54:57.516: E/AndroidRuntime(29949): at com.amplimesh.models.ModelGLRenderer$ObjLoaderAsync.doInBackground(ModelGLRenderer.java:138)
09-12 12:54:57.516: E/AndroidRuntime(29949): at com.amplimesh.models.ModelGLRenderer$ObjLoaderAsync.doInBackground(ModelGLRenderer.java:1)
09-12 12:54:57.516: E/AndroidRuntime(29949): at android.os.AsyncTask$2.call(AsyncTask.java:264)
09-12 12:54:57.516: E/AndroidRuntime(29949): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
09-12 12:54:57.516: E/AndroidRuntime(29949): ... 5 more
I think you are mistaken with the meaning of the continue keyword. This keyword means that the loop jumps immediately to the next iteration without executing the rest of the code in the loop block.
In your case, it means that this code
i = localFileInputStream.read();
if (i != -1)
continue;
localFileInputStream.close();
if ((char) i == 'v') {
i = localFileInputStream.read();
closes the inputStream, and then tries to read from it. You algorithm is not very clear because of all the continues, so I can't really tell you how to fix that.
#Override
protected void onPostExecute(Void param) {
try {
mr[getCurrentPosition()] = new ModelRenderer(localContext,
localContext.getAssets().open(RendererView.objName));
dialog.cancle();
} catch (java.io.IOException e) {
Log.v("DemoRendererView", "loading model: " + e);
}
}
please check this...
you start with
try {
i = localFileInputStream.read();
if (i != -1)
continue;
localFileInputStream.close();
so, you are closing the stream and after that you are trying to read again from it. Also you are running this inside an infinite loop and exit from it only in a the catch section. Consider closing the stream after you are done reading it.
I am trying to avoid using onDestroy and want to keep this as simple as possible, but when I exit the program, I get a Force Close error. Not sure why. Here is the code for the main part of the application. Any suggestions?
Main Application Code
public class Quotes extends Activity implements OnClickListener {
ProgressDialog dialog;
private WebView webview;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
WebView adsview = (WebView) findViewById(R.id.ads);
adsview.getSettings().setJavaScriptEnabled(true);
adsview.loadUrl("http://www.dgdevelco.com/quotes/androidad.html");
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String q = SP.getString("appViewType","http://www.dgdevelco.com/quotes/quotesandroidtxt.html");
String c = SP.getString("appRefreshRate","20");
webview = (WebView) findViewById(R.id.scroll);
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebViewClient(new QuotesWebView(this));
webview.loadUrl(q);
ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor();
timer.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
webview.reload();
}
}, 10, Long.parseLong(c),TimeUnit.SECONDS);
findViewById(R.id.refresh).setOnClickListener(this);
}
#Override
public void onPause(){
super.onPause();
}
#Override
public void onResume(){
super.onResume();
}
public void onClick(View v){
switch(v.getId()){
case R.id.refresh:
webview.reload();
break;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
MenuItem about = menu.getItem(0);
about.setIntent(new Intent(this, About.class));
MenuItem preferences = menu.getItem(1);
preferences.setIntent(new Intent(this, Preferences.class));
return true;
}
}
LogCat
07-04 13:34:55.011: INFO/DevicePushListener(1415): Connection State Changed: NetworkInfo: type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: (none), roaming: false, failover: false, isAvailable: true
07-04 13:34:55.011: WARN/WindowManager(1314): Attempted to add application window with unknown token HistoryRecord{40c40f50 com.dge.quotes/.Quotes}. Aborting.
07-04 13:34:55.034: DEBUG/AndroidRuntime(24137): Shutting down VM
07-04 13:34:55.034: WARN/dalvikvm(24137): threadid=1: thread exiting with uncaught exception (group=0x40018560)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): FATAL EXCEPTION: main
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy#40517fb0 is not valid; is your activity running?
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at android.view.ViewRoot.setView(ViewRoot.java:527)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at android.view.Window$LocalWindowManager.addView(Window.java:424)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at android.app.Dialog.show(Dialog.java:241)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at android.app.ProgressDialog.show(ProgressDialog.java:107)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at android.app.ProgressDialog.show(ProgressDialog.java:90)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at com.dge.quotes.QuotesWebView.onPageStarted(QuotesWebView.java:22)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:271)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at android.os.Handler.dispatchMessage(Handler.java:99)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at android.os.Looper.loop(Looper.java:123)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at android.app.ActivityThread.main(ActivityThread.java:3806)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at java.lang.reflect.Method.invokeNative(Native Method)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at java.lang.reflect.Method.invoke(Method.java:507)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-04 13:34:55.058: ERROR/AndroidRuntime(24137): at dalvik.system.NativeStart.main(Native Method)
07-04 13:34:55.089: WARN/ActivityManager(1314): Force finishing activity com.dge.quotes/.Quotes
Its written in your stacktrace
Unable to add window -- token android.os.BinderProxy#40517fb0 is not valid; is your activity running
You start a thread that does a reload
You then press back
Your activity finished
The thread returns and tries to draw on your activity
Oops its already finished
Take a look at the example code provided on the ScheduledExecutorService documentation page:
import static java.util.concurrent.TimeUnit.*;
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep");
};
final ScheduledFuture beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() { beeperHandle.cancel(true); }
}, 60 * 60, SECONDS);
}
}}
(http://developer.android.com/reference/java/util/concurrent/ScheduledExecutorService.html)
As others have said, the problem is that the ScheduledExecutorService keeps running and reloading the page even after the user closes that activity. To fix this, you can stop the ScheduledExecutorService in onPause.
Calling scheduleAtFixedFate() returns a ScheduledFuture object. Store this object and then call cancel(true) on it in your onPause() method.
Your activity is already stopped when it reaches that line of code. Refer to the exchange in this "bug" report in the Android forum: http://code.google.com/p/android/issues/detail?id=3953