I am new here to Android. My application is crashing with errors after sleep runs (5000) and then my toast is not showing in my finally block. What is causing these errors in my code?
public class LoginActivity extends ActionBarActivity {
TextView textview;
Toast toast;
#Override
protected void onCreate(Bundle ThisisLoginActivity) {
super.onCreate(ThisisLoginActivity);
setContentView(R.layout.activity_login);
textview = (TextView) findViewById(R.id.textView1);
Thread thread = new Thread() {
public void run() {
try{
sleep(5000);
} catch(InterruptedException e) {
e.printStackTrace();
}
finally {
toast = Toast.makeText(getApplicationContext(), "Sleep Runing", Toast.LENGTH_SHORT);
toast.show();
}
}
};
thread.start();
}
}
Here is my LogCat:
01-08 22:30:32.782: E/Trace(3503): error opening trace file: No such file or directory (2)
01-08 22:30:33.322: I/Choreographer(3503): Skipped 47 frames! The application may be doing too much work on its main thread.
01-08 22:30:33.402: D/gralloc_goldfish(3503): Emulator without GPU emulation detected.
01-08 22:30:33.531: I/Choreographer(3503): Skipped 62 frames! The application may be doing too much work on its main thread.
01-08 22:30:39.122: I/Choreographer(3503): Skipped 31 frames! The application may be doing too much work on its main thread.
01-08 22:30:39.272: I/Choreographer(3503): Skipped 43 frames! The application may be doing too much work on its main thread.
01-08 22:30:45.772: W/dalvikvm(3503): threadid=11: thread exiting with uncaught exception (group=0x40a71930)
01-08 22:30:45.792: E/AndroidRuntime(3503): FATAL EXCEPTION: Thread-153
01-08 22:30:45.792: E/AndroidRuntime(3503): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
01-08 22:30:45.792: E/AndroidRuntime(3503): at android.os.Handler.<init>(Handler.java:197)
01-08 22:30:45.792: E/AndroidRuntime(3503): at android.os.Handler.<init>(Handler.java:111)
01-08 22:30:45.792: E/AndroidRuntime(3503): at android.widget.Toast$TN.<init>(Toast.java:324)
01-08 22:30:45.792: E/AndroidRuntime(3503): at android.widget.Toast.<init>(Toast.java:91)
01-08 22:30:45.792: E/AndroidRuntime(3503): at android.widget.Toast.makeText(Toast.java:238)
01-08 22:30:45.792: E/AndroidRuntime(3503): at com.example.incrementdecrement.LoginActivity$1.run(LoginActivity.java:48)
01-08 22:30:46.462: I/Choreographer(3503): Skipped 34 frames! The application may be doing too much work on its main thread.
You cannot directly manipulate the user interface from another thread. The main thread is responsible for all UI changes.
For a solution to a similiar problem see: Android: Toast in a thread
Just use Activity's runOnUiThread method from your thread:
runOnUiThread(new Runnable() {
public void run()
{
Toast.makeText(LoginActivity.this, "Sleep Runing", Toast.LENGTH_SHORT).show();
}
});
Method in onCreate :
private void toastPublic(final String message){
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
Toast.makeText(getBaseContext(),""+message,
4 /*Toast.LENGTH_SHORT*/).show();
}});
}
Next : use in inside Thread
Related
I have been able to set up a connection between my socket server (running on ruby) and my client, which is an Android(java) application. I will explain what my goal is.
I have to send a string to my server through the socket. Depending on the contents of the string, the server would execute a process in the database (store, delete, view data, etc).
The first option is to validate the user name/password. Im able to send the correct string, and the server receives it and replies back to me with the correct response (after validating whether or not my username is capable of logging into the application). Now, depending on this response i need to change the current activity (loginActivity) with the next activity (MenuActivity) so that the user can proceed to use the application menu.
Since the socket has to run on a different thread other than the UIThread, im running it using the AsyncTask way. However im having problems triggering the activity change thing after the AsyncTask process is over.
What im doing is, after the whole Async task is done (onPostExecute method) im trying to call up the activity, but its not working. This is what i've tried (based on similar cases i've found during research):
(AsyncTask class)
Context context;
private void AppContext(Context context) {
this.context = context.getApplicationContext();
}
OnPostExecute
Intent NewActivity = new Intent();
NewActivity.setClass(context.getApplicationContext(),MainActivity.class);
context.startActivity(NewActivity);
However this is not working and its causing my app to crash with a "thread exciting with uncaught exception"
I've tried showing only a Toast message that says "Granted" or "Denied" just to test it with a simpler task, but i keep getting the same error so im assuming its got to do with handling the change between the thread on which the Async task is running and the UI thread. Any ideas?
P.S: I've checked the other questions that are similar to mine and tried the suggested code, but nothing's worked.
ERROR LOG
09-29 09:59:11.387: E/AndroidRuntime(2856): FATAL EXCEPTION: main
09-29 09:59:11.387: E/AndroidRuntime(2856): java.lang.NullPointerException
09-29 09:59:11.387: E/AndroidRuntime(2856): at com.example.prescoterm.SocketClass.onPostExecute(SocketClass.java:111)
09-29 09:59:11.387: E/AndroidRuntime(2856): at com.example.prescoterm.SocketClass.onPostExecute(SocketClass.java:1)
09-29 09:59:11.387: E/AndroidRuntime(2856): at android.os.AsyncTask.finish(AsyncTask.java:602)
09-29 09:59:11.387: E/AndroidRuntime(2856): at android.os.AsyncTask.access$600(AsyncTask.java:156)
09-29 09:59:11.387: E/AndroidRuntime(2856): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
09-29 09:59:11.387: E/AndroidRuntime(2856): at android.os.Handler.dispatchMessage(Handler.java:99)
09-29 09:59:11.387: E/AndroidRuntime(2856): at android.os.Looper.loop(Looper.java:137)
09-29 09:59:11.387: E/AndroidRuntime(2856): at android.app.ActivityThread.main(ActivityThread.java:4424)
09-29 09:59:11.387: E/AndroidRuntime(2856): at java.lang.reflect.Method.invokeNative(Native Method)
09-29 09:59:11.387: E/AndroidRuntime(2856): at java.lang.reflect.Method.invoke(Method.java:511)
09-29 09:59:11.387: E/AndroidRuntime(2856): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-29 09:59:11.387: E/AndroidRuntime(2856): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-29 09:59:11.387: E/AndroidRuntime(2856): at dalvik.system.NativeStart.main(Native Method)
Ok so i found a workaround this, now i would like to hear from you guys if you think this'd be a suitable solution.
Since the problem was that the context was coming up null at my AsyncTask class, i decided to load the value on a variable from the moment the application start.
context = this.getApplicationContext();
new SocketReception().setContext(context);
On my SocketReception Class i had a setContext(context) method.
public void setContext(Context context)
{
SocketReception.appContext= context;
};
Now, on my AsyncTask post.execute i call the new activity like this:
SocketReception.appContext.startActivity(NewActivity);
Its now working, but i want to know if this is a convenient approach or if i should keep looking for a different solution.
P.S: I had to add the unpopular "FLAG_ACTIVITY_NEW_TASK", will research on how to avoid this later on.
I have used this asynctask directly in activity and work fine, may be help. When i try call Intent i = new Intent(getApplicationContext(), VyberIcoActivitySD.class); in class without context ( class extended not Activity, Fragment... ) i have not result...
class SynchroAllIcosSD extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(SynchroIcoActivitySD.this);
pDialog.setMessage(getString(R.string.progdata));
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
//do something
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
Intent i = new Intent(getApplicationContext(), VyberIcoActivitySD.class);
Bundle extras = new Bundle();
extras.putString("odkade", "100");
extras.putString("page", "1");
i.putExtras(extras);
startActivity(i);
finish();
}
});
}
}
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.
This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 8 years ago.
I make simply rss reader in android. I have the errors (I searched and tried some solutions but nothing):
Couldn't open http://pogoda.wp.pl/rss.xml
java.io.IOException: Couldn't open http://pogoda.wp.pl/rss.xml
at org.apache.harmony.xml.ExpatParser.openUrl(ExpatParser.java:755)
at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:292)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:390)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:266)
at com.newsreader.RssReader.getItems(RssReader.java:23)
at com.newsreader.MainActivity$1$1.run(MainActivity.java:48)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4340)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1084)
at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
at java.net.InetAddress.getAllByName(InetAddress.java:220)
at libcore.net.http.HttpConnection.<init>(HttpConnection.java:71)
at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
at libcore.net.http.HttpEngine.connect(HttpEngine.java:303)
at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
at org.apache.harmony.xml.ExpatParser.openUrl(ExpatParser.java:753)
and activity:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(){
public void run(){
MainActivity.this.runOnUiThread(new Runnable(){
#Override
public void run() {
try{
RssReader reader = new RssReader("http://pogoda.wp.pl/rss.xml");
ListView items = (ListView) findViewById(R.id.listView1);
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(MainActivity.this, android.R.layout.simple_list_item_1, reader.getItems());
items.setAdapter(adapter);
Log.i("", ""+reader);
items.setOnItemClickListener(new ListListener(reader.getItems(), MainActivity.this));
}catch(Exception e){
Log.e("blad", e.getMessage(), e);
}
}
});
}
}.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
I don't know what am I doing wrong. Maybe someone has got the same problem so please help.
Thanks
It is because you are performing network operation on main thread of activity. Using Async task will be a better option.
Caused by: android.os.NetworkOnMainThreadException
This speaks for itself.
Don't do networking on the main Thread!
AsyncTask to the rescue. Try it out it will work.
Always use AsyncTask to solve this issue.
BUT, if you're within the movie Swordfish, someone points a gun at you and say "fix it in 30 seconds", then change your targetSdkVersion to 9 in the Android Manifest and the exception will stop. Don't worry, it will run on devices with version higher than 9 too. Even so, correct your code later using AsyncTask.
I'm trying to get a looper thread to work but despite all attempts, it crashes. I'm not using the HandlerThread class, as I'm doing quite a bit of 802.11 related stuff in the thread itself and posting Runnables with lots of duplicate code doesn't seem to be the right way to go here.
Here the skeleton of the looper thread class:
public class WiFiScanner extends Thread {
Looper mLooper;
Handler mHandler;
#Override
public void run() {
Looper.prepare();
synchronized(this) {
mLooper = Looper.myLooper();
notifyAll();
}
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
..... // message parsing
}
}
}
/* waits for Looper initialization */
public boolean waitForLooper() {
synchronized(this) {
while(mLooper == null) {
try {
wait();
} catch (InterruptedException e) {}
}
}
return true;
}
}
and the code initializing it in the main activity:
wifiScanner = new WiFiScanner(
... // callback stuff
);
wifiScanner.start();
wifiScanner.waitForLooper();
wifiScanner.initialize();
initialize is a simple function in the WiFiScanner class, posting a message bundle to the message queue:
public void initialize() {
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
WiFiMsg msgId = WiFiMsg.INITIALIZE;
b.putSerializable("msgId", msgId);
msg.obj = b;
mHandler.sendMessage(msg);
}
Despite waitForLooper() returning successfully, the call to initialize() causes a null pointer exception. I assume the looper isn't really in a state to have message dispatched into the queue as a static delay of 500ms between waitForLooper() and initialize() circumvents this issue.
Any ideas on how to fix this in a reasonably elegant way?
PS: Now by popular demand, a stack trace:
E/AndroidRuntime( 3178): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
E/AndroidRuntime( 3178): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
E/AndroidRuntime( 3178): at android.app.ActivityThread.access$600(ActivityThread.java:141)
E/AndroidRuntime( 3178): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
E/AndroidRuntime( 3178): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 3178): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime( 3178): at android.app.ActivityThread.main(ActivityThread.java:5103)
E/AndroidRuntime( 3178): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 3178): at java.lang.reflect.Method.invoke(Method.java:525)
E/AndroidRuntime( 3178): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
E/AndroidRuntime( 3178): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
E/AndroidRuntime( 3178): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 3178): Caused by: java.lang.NullPointerException
E/AndroidRuntime( 3178): at de.uni_leipzig.informatik.rvs.videodownload.wifi.WiFiScanner.initialize(WiFiScanner.java:204)
E/AndroidRuntime( 3178): at de.uni_leipzig.informatik.rvs.videodownload.MainActivity.onCreate(MainActivity.java:270)
E/AndroidRuntime( 3178): at android.app.Activity.performCreate(Activity.java:5133)
E/AndroidRuntime( 3178): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
E/AndroidRuntime( 3178): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
E/AndroidRuntime( 3178): ... 11 more
Your notify should be after mHandler is set, not mLooper - since your NPE is on mHandler.
Hi I am trying to execute the code below it suppose to open a loading dialog and dismiss it in the if statement.
here is the code:
loginBtn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View view)
{
final ProgressDialog progress = ProgressDialog.show(thisActivity, "Please wait", "Loading please wait..", true);
Thread loginThread = new Thread(new Runnable()
{
#Override
public void run()
{
try
{
boolean userAllowed = login.loginUser(userEmail.getText().toString(), userPass.getText().toString());
if(userAllowed)
{
progress.dismiss();
startActivity(mainPage);
}
else
{
progress.dismiss();
Toast.makeText(context, "Invalide email and password", Toast.LENGTH_LONG).show();
}
}
catch (Exception e)
{
Toast.makeText(context, "There is some problem", Toast.LENGTH_LONG).show();
}
}
});
loginThread.start();
}
});
the logCat error output is:
05-09 22:37:26.508: E/AndroidRuntime(24820): FATAL EXCEPTION: Thread-1306
05-09 22:37:26.508: E/AndroidRuntime(24820): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-09 22:37:26.508: E/AndroidRuntime(24820): at android.os.Handler.<init>(Handler.java:197)
05-09 22:37:26.508: E/AndroidRuntime(24820): at android.os.Handler.<init>(Handler.java:111)
05-09 22:37:26.508: E/AndroidRuntime(24820): at android.widget.Toast$TN.<init>(Toast.java:324)
05-09 22:37:26.508: E/AndroidRuntime(24820): at android.widget.Toast.<init>(Toast.java:91)
05-09 22:37:26.508: E/AndroidRuntime(24820): at android.widget.Toast.makeText(Toast.java:238)
05-09 22:37:26.508: E/AndroidRuntime(24820): at com.shale.activities.MainActivity$1$1.run(MainActivity.java:93)
05-09 22:37:26.508: E/AndroidRuntime(24820): at java.lang.Thread.run(Thread.java:856)
My reference was this tutorial.
Thanks!
as in Log :
RuntimeException: Can't create handler inside thread that has not
called Looper.prepare()
means you are trying to update or access UI elements from non ui Thread . so you will need to use Activity.runOnUiThread , Handler or AsyncTask for updating or accessing UI from other Thread. do it as:
Your_Activity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
//update Ui elements here
}
});
You can't do anything UI related (including dismissing dialogs) unless you're on the UI thread. You need to offload that via a runOnUiThread or by passing a message to a handler on the UI thread. Or better yet- make that thread an AsyncTask and do it in the onPostExecute()
An alternative to the above would be to send a broadcast and have a BroadcastReceiver handle receiving that broadcast and act upon it as you wish.