Timer error when calling asyntask in Android - java

I have this timer inside a service, it works perfectly and count... but when i call some asyntask's it gives me error!!
Timer time = new Timer(); // Instantiate Timer Object
time.schedule(new TimerTask(){
public void run() {
// i call my Asyntasks here
}
},5000,5000);
this gives me error:
03-17 02:02:27.167: E/AndroidRuntime(925): FATAL EXCEPTION: Timer-0
03-17 02:02:27.167: E/AndroidRuntime(925): java.lang.ExceptionInInitializerError
03-17 02:02:27.167: E/AndroidRuntime(925): at Dic.proj.pkg.notifService$1.run(notifService.java:57)
03-17 02:02:27.167: E/AndroidRuntime(925): at java.util.Timer$TimerImpl.run(Timer.java:289)
03-17 02:02:27.167: E/AndroidRuntime(925): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
03-17 02:02:27.167: E/AndroidRuntime(925): at android.os.Handler.<init>(Handler.java:121)
03-17 02:02:27.167: E/AndroidRuntime(925): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
03-17 02:02:27.167: E/AndroidRuntime(925): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
03-17 02:02:27.167: E/AndroidRuntime(925): at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
03-17 02:02:27.167: E/AndroidRuntime(925): ... 2 more
if i put others instructions like Log.d("message"); everythings goes OK

AsynchTask needs to be created/called from a UI thread or at least a thread with a looper to handle callbacks when the task wants to publish anything to the caller thread such as onPostExcute() ... and using Timer object which runs in its own thread doesn't satisfy this condition.
I suggest you use Handler combined with Timer to achieve this, or even create your own timer using handler object.
The first idea would look something like this:
final Handler handler = new Handler();
Timer time = new Timer(); // Instantiate Timer Object
time.schedule(new TimerTask(){
public void run() {
handler.post(new Runnable(){
// i call my Asyntasks here
});
}
},5000,5000);
Take a look here to read more about Handlers and Timers:
Timer
AsynchTask
and here is a good tutorial about threads:
Tutorials

It seems, you should be inside UI-thread to start AsyncTasks.
You can try to use Handler.postDelayed(Runnale, long) instead of Timer.

The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
The task instance must be created on the UI thread.
You are creating a new thread. Use a handler. Runs on the main thread
private Handler handler = new Handler();
Runnable task = new Runnable() {
#Override
public void run() {
//do something
handler.postDelayed(this, 100000);
}
};
handler.removeCallbacks(task);
handler.post(task);
http://developer.android.com/reference/android/os/AsyncTask.html

Related

ExceptionInInitializerError When trying to call a TimerTask from Main Android application in a library module

I have a TimerTask in a library module I use, I have access to the source code and it worked independantly, however when I call the method startPoll()from the main application i get the following error, SensorPoll is the TimerTask:
E/AndroidRuntime: FATAL EXCEPTION: Timer-0
Process: com.app, PID: 29465
java.lang.ExceptionInInitializerError
at com.app.Utilities.SensorPoll.run(SensorPoll.java:55)
at java.util.TimerThread.mainLoop(Timer.java:562)
at java.util.TimerThread.run(Timer.java:512)
Caused by: java.lang.RuntimeException: Can't create handler inside thread Thread[Timer-0,5,main] that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:207)
at android.os.Handler.<init>(Handler.java:119)
at com.app.MainActivity.<clinit>(MainActivity.java:31)
at com.ap.Utilities.SensorPoll.run(SensorPoll.java:55) 
at java.util.TimerThread.mainLoop(Timer.java:562) 
at java.util.TimerThread.run(Timer.java:512) 
The error is on the public void run(){ line in the TimerTask.
I need to be able to run this, i don't try to call it from an AsyncTask, just from inside onCreateView in a fragment. It's actaully called from within the onFinish() of a CountDownTimer(). How can i avoid this error and start my TimerTask on it's Thread? If you need anymore info please ask.
The Code:
The Call
new CountDownTimer(10000, 1000){
#Override
public void onTick(long millisUntilFinished) {
countdown.setText(String.valueOf(String.valueOf(counter)));
counter--;
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onFinish() {
countdown.setText("Initialised");
srace.startSrace();
}
}.start();
The Method which calls the PollDirectly:
public void startSrace(){
sraceManager.startPoll();
}
The startPoll Method:(We are now in the Module Library)
public static void startPoll() {
TimerTask sensorPoll = new SensorPoll();
Timer timer = new Timer();
timer.scheduleAtFixedRate(sensorPoll, 0L, 9L);
}
SensorPoll - The TimerTask
public SensorPoll() {
}
#RequiresApi(
api = 24
)
//This is the error line-->
public void run() {
//Just gets sensor info in here
}
Not much too it. Thanks

Basic Background service tries to open a socket

I'm trying to have an app which simply starts a background service whenever a button is pressed. The background app should then open a connection using a socket to a server and then send some dummy data. After having done so, the service should die.
I'm currently getting a java.lang.IllegalStateException when I click the button and the whole application stops.
Here is what I have so far in my main activity.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void start_clicked(View view) {
Intent my_intent = new Intent(this,BackgroundService.class);
startActivity(my_intent);
}
}
Here is the XML corresponding to the button and to the background service:
This is Activity_Main.xml
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start"
android:id="#+id/button"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:onClick="start_clicked"/>
This is the Android Manifest corresponding to the service
<service android:name="com.example.g.backgroundsensor.BackgroundService"
android:exported="true"
android:enabled="true" >
</service>
And finally here is the actual BackgroundService class (fragments which I think caused the error)
public class BackgroundService extends Service {
private Socket my_socket;
public BackgroundService() {
try {
my_socket = new Socket(ip, 5000);
}catch(Exception e){
}
}
public int onStartCommand(Intent intent, int flags, int startId) {
try {
DataOutputStream my_stream = new DataOutputStream(my_socket.getOutputStream());
my_stream.write(121);
}catch(Exception e){
}
stopSelf();
return 1;
}
What is causing this error and how could I (in the future) debug this myself since the console is relatively vague:
---/com.example.g.backgroundsensor E/AndroidRuntime: FATAL EXCEPTION: main
---/com.example.g.backgroundsensor E/AndroidRuntime: Process: com.example.g.backgroundsensor, PID: 9876
---/com.example.g.backgroundsensor E/AndroidRuntime: java.lang.IllegalStateException: Could not execute method of the activity
To start a Service you should use startService() and not startActivity()
Intent my_intent = new Intent(this, BackgroundService.class);
startService(my_intent);
I don't know how one would debug that, but you should always make sure what you are calling where and which arguments you are passing.
First you have to create a Intent Service instead of service because intent service is called on UI thread and android doesn't allow any network call on UI thread take a look at code below
public class SocketService extends IntentService {
#Override
protected void onHandleIntent(Intent workIntent) {
//CONNECT SOCKET HERE
}
}
then register this service in Manifest
<application>
<service android:name=".SocketService" />
</application>
and then start your service like this
startService(new Intent(this, SocketService.class));
//YOU HAVE USED startActivity INSTEAD OF startService
I have a similar app and my Manifest only contains this:
<service android:name=".ServiceActivity" />
inside the application tag, just before activity tag. Besides that, your Manifest should explicit:
<uses-permission android:name="android.permission.INTERNET" />
There are two problems in this code.
To start a service that should run in background you need started service hence you need to call startservice() :
Intent my_intent = new Intent(this, BackgroundService.class);
startService(my_intent);
Second big problem is that the way you have created your service. It will by default start on UI thread. So, in this scenario you should have either use IntentService or service on a separate thread.
Intent Service :
public class BackgroundService extends IntentService {
private Socket my_socket;
#Override
protected void onHandleIntent(Intent workIntent) {
try {
my_socket = new Socket(ip, 5000);
DataOutputStream my_stream = new DataOutputStream(my_socket.getOutputStream());
my_stream.write(121);
}catch(Exception e){
}
}
}
Major benefit of intent service is that it will call stopSelf once all the work is done and there are no more requests. Second is that all the work will be done in background.
Service on a seperate thread :
public class BackgroundService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
#Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
#Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
#Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
#Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
I would suggest using intentservice as it is simple and perfect for your scenario.
What is causing this error
startActivity is called instead of startService
how could I (in the future) debug this myself since the console is relatively vague
This is the interesting part, the message should be followed by a full stack trace, that is explicitly describing the error. Like this one :
02-10 12:26:52.734: E/AndroidRuntime(16214): FATAL EXCEPTION: main
02-10 12:26:52.734: E/AndroidRuntime(16214): Process: com.example.sandbox, PID: 16214
02-10 12:26:52.734: E/AndroidRuntime(16214): java.lang.IllegalStateException: Could not execute method for android:onClick
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.view.View$DeclaredOnClickListener.onClick(View.java:4458)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.view.View.performClick(View.java:5204)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.view.View$PerformClick.run(View.java:21153)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.os.Handler.handleCallback(Handler.java:739)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.os.Handler.dispatchMessage(Handler.java:95)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.os.Looper.loop(Looper.java:148)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.app.ActivityThread.main(ActivityThread.java:5417)
02-10 12:26:52.734: E/AndroidRuntime(16214): at java.lang.reflect.Method.invoke(Native Method)
02-10 12:26:52.734: E/AndroidRuntime(16214): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
02-10 12:26:52.734: E/AndroidRuntime(16214): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
02-10 12:26:52.734: E/AndroidRuntime(16214): Caused by: java.lang.reflect.InvocationTargetException
02-10 12:26:52.734: E/AndroidRuntime(16214): at java.lang.reflect.Method.invoke(Native Method)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.view.View$DeclaredOnClickListener.onClick(View.java:4453)
02-10 12:26:52.734: E/AndroidRuntime(16214): ... 9 more
02-10 12:26:52.734: E/AndroidRuntime(16214): Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.sandbox/com.example.sandbox.BackgroundService}; have you declared this activity in your AndroidManifest.xml?
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1794)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1512)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.app.Activity.startActivityForResult(Activity.java:3930)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.app.Activity.startActivityForResult(Activity.java:3890)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.app.Activity.startActivity(Activity.java:4213)
02-10 12:26:52.734: E/AndroidRuntime(16214): at android.app.Activity.startActivity(Activity.java:4181)
02-10 12:26:52.734: E/AndroidRuntime(16214): at com.example.sandbox.MainActivity.start_clicked(MainActivity.java:19)
02-10 12:26:52.734: E/AndroidRuntime(16214): ... 11 more
The part Unable to find explicit activity class com.example.sandbox/com.example.sandbox.BackgroundService}; have you declared this activity in your AndroidManifest.xml? is very clear and it should be easy to fix the issue just reading it.

Async PostExecute

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();
}
});
}
}

Threads in Background Service Android

Hi I am trying to use the service class for first time and have been facing problems. What I want is an infinitely running (unless killed by Android System) service with an active Network connection. I have written the code which works fine on Android 4.3 and 4.4 but the application crashes when I try running on Android 2.2. My code is as follows:
public class BackgroundMusicService extends Service {
private MediaPlayer mp;
private int id;
private static class BackgroundAsyncTaskClass extends AsyncTask<Void, Void, Void>{
protected Void doInBackground(Void... params) {
Log.v("Async","Async Called");
/*Network connection will be created here*/
return null;
}
}
private class ForThread implements Runnable{
public void run() {
while (true) {
try {
Log.v("ThreadSleeping","5 sec");
BackgroundAsyncTaskClass task = new BackgroundAsyncTaskClass();
task.execute();
Thread.sleep(5000);
} catch (InterruptedException e) {
}finally{
Log.v("Finally called","Finally called");
}
}
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v("onStartCommand Called","onStart Command Called");
Thread t;
ForThread ft = new ForThread();
t = new Thread(ft);
t.start();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
if(null != mp){
mp.stop();
mp.release();
Log.v("Destroyed","onDestroy Called");
}
}
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(),
this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(
getApplicationContext(), 1, restartServiceIntent,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext()
.getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartServicePendingIntent);
super.onTaskRemoved(rootIntent);
}
}
and the exception thrown by Android 2.2 is as follows:
04-28 09:51:41.435: W/dalvikvm(280): threadid=7: thread exiting with uncaught exception (group=0x4001d800)
04-28 09:51:41.435: E/AndroidRuntime(280): FATAL EXCEPTION: Thread-8
04-28 09:51:41.435: E/AndroidRuntime(280): java.lang.ExceptionInInitializerError
04-28 09:51:41.435: E/AndroidRuntime(280): at com.example.backgroundservicedemo.BackgroundMusicService$ForThread.run(BackgroundMusicService.java:45)
04-28 09:51:41.435: E/AndroidRuntime(280): at java.lang.Thread.run(Thread.java:1096)
04-28 09:51:41.435: E/AndroidRuntime(280): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-28 09:51:41.435: E/AndroidRuntime(280): at android.os.Handler.<init>(Handler.java:121)
04-28 09:51:41.435: E/AndroidRuntime(280): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
04-28 09:51:41.435: E/AndroidRuntime(280): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
04-28 09:51:41.435: E/AndroidRuntime(280): at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
Also, when I try using handler.post(new Runnable(){.... run(){}....} The UI hangs up but the background thread continues running and exits after it becomes out of memory.
Another thing that I have doubts about is:
When the application restarts, I want this active Service to stop, but how do I get a reference to this thread running in Background and how do I stop this? I would appreciate if anyone can redirect me to a suitable link/reference or could help me out with the code. Thanks
You have this inside a thread's run method
BackgroundAsyncTaskClass task = new BackgroundAsyncTaskClass();
task.execute();
Threading rules from the docs
The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)

implement Runnable Run() when thread is started

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.

Categories

Resources