Stop simple timer with a tread - java

I'm trying to stop a timer from a thread which start the count. When i press the "START" button everything is okay, but at the moment i press the "STOP" button i get the next error:
FATAL EXCEPTION: main
Process: com.example.user.a4_1_basic_handler, PID: 20375
java.lang.IllegalStateException: Could not execute method for android:onClick
I'm new at this, i'm just trying to put in practice thread using handler. If someone can tell me how to finish the thread that will be a plus :)
package com.example.user.a4_1_basic_handler;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
//Java variables
int num =0;
boolean stopThread=false;
//Android variables
static final String S_TAG=MainActivity.class.getSimpleName();
Handler handler;
Thread counter = new Thread(new tstart());
tstart test;
// UI
TextView textView;
Button start_button;
Button stop_button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(S_TAG,"OnCreate Thread ID: "+Thread.currentThread().getId());
handler = new Handler(getApplicationContext().getMainLooper());
tstart test;
textView=(TextView) findViewById(R.id.textView);
start_button=(Button) findViewById(R.id.start_button);
stop_button=(Button) findViewById(R.id.stop_button);
}
//UI
public void OnClick_start(View view){
counter.start();
}
public void OnClick_stop(View view){
test.finish();
}
//Methods
public void timer(){
num++;
textView.setText(String.valueOf(num));
}
public void clock(){
try {Thread.sleep(1000);}
catch (InterruptedException e) {e.printStackTrace();}
}
//Thread
class tstart extends Thread{
#Override
public void run() {
while (!stopThread) {
clock();
textView.post(new Runnable() {
#Override
public void run() {
timer();
}
});
}
}
public void finish(){
stopThread=true;
}
}
}

test is not initialisd.
Thread counter = new Thread(new tstart());
What is the need of counter, inside onCreate() create object of test
test=new tstart();
And use test instead of counter
public void OnClick_start(View view){
test.start();
}
Why don't you try Standard Java timer java.util.Timer and java.util.TimerTask that works fine in Android.

Related

How can i call multiple methods on background thread, in java Android. I need to call them at different instant of time

package com.example.understandingthread;
import androidx.appcompat.app.AppCompatActivity;
import android.nfc.cardemulation.HostNfcFService;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Runnable r1 = new Runnable() {
#Override
public void run() {
// method1();
}
};
Thread t1 = new Thread(r1);
t1.start();
//Doing some other operations i have to do
Runnable r2 = new Runnable() {
#Override
public void run() {
// method2();
}
};
Thread t2 = new Thread(r2);
t2.start();
//Doing some more operations, some for loops which will give me data
//to pass in method 3
Runnable r3 = new Runnable() {
#Override
public void run() {
// method3(parameter 1, parameter 2,parameter 3);
}
};
Thread t3 = new Thread(r3);
t3.start();
}
}
// Do i need to implement runnable for each method, or if i do it by extending thread class, do i need to create 3 different classes if i have to call 3 methods.
Is there any other better method than i have used?

UI-Thread getting blocked when Thread.sleep() called in another thread

I am trying to read a text file from SD-Card in a Runnable called PcmDataReader and updating a TextView statusTextView , accordingly in the UI-Thread.
I am using a handler to pass the messages from PcmDataReader to the UI-Thread.
In order to be able to observe the change of statusTextView I have put a Thread.sleep(5000) in PcmDataReader.
The issue is that the UI-Thread is blocked until the file i/o & the sleep are finished & the final update i.e. "File Reading Complete.." is only shown on statusTextview.
What am I missing here ? Following is my code:
MainActivity.java:
package com.example.pcmreader;
import android.Manifest;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private TextView statusTextView ;
priavte Button updateButton;
private PcmDataReader pcmData = new PcmDataReader();
private static Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
handler = new Handler()
{
#Override
public void handleMessage (Message message)
{
String msg = (String) message.obj;
if (statusTextView != null)
statusTextView.setText(msg);
}
};
setContentView(R.layout.main);
statusTextView= (TextView) findViewById(R.id.statusTextView);
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.READ_EXTERNAL_STORAGE }, 100);
updateButton.setOnClickListener(this);
}
#Override
public void onClick(View view)
{
statusTextView.setText("Initiating Read .. ");
pcmData.run();
}
public static Handler getHandler ()
{
return handler;
}
}
PcmDataReader.java:
package com.example.pcmreader;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class PcmDataReader implements Runnable
{
private int [] samples = new int[6000];
private int i;
private boolean completedReading;
private File sdcard = Environment.getExternalStorageDirectory();
private File file = new File(sdcard,"rishav_log.txt");
#Override
public void run()
{
i=0;
completedReading = false;
try
{
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
Handler uiHandler= MainActivity.getHandler();
Message msg = uiHandler.obtainMessage();
msg.obj="File openned, Reading data..";
uiHandler.sendMessage(msg);
while ((line = br.readLine()) != null)
samples[i++]=Integer.parseInt(line);
Thread.sleep(5000); //dummy sleep to observe the update of textView in UI thead
br.close();
completedReading = true;
msg = uiHandler.obtainMessage();
msg.obj="File Reading Complete..";
uiHandler.sendMessage(msg);
}
catch (IOException e)
{
Log.i("file read",e.getMessage());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
Calling runnable should be in separate thread.
Replace
pcmData.run();
to
Thread t1 =new Thread(pcmData);
t1.start();
The UI thread freezes because you call the Thread.sleep() in the same thread:
#Override
public void onClick(View view) {
statusTextView.setText("Initiating Read .. ");
pcmData.run(); // PcmDataReader.run() will happen in the UI thread
}
The fix is relatively easy:
#Override
public void onClick(View view) {
statusTextView.setText("Initiating Read .. ");
ExecutorService executor = Executors.newSingleThreadExecutor(); // this can come from somplace else.
// Actually, it better comes from someplac else.
executor.submit(pcmData); // this is how to run in in a background thread.
// executor.shutdown(); // this is necessary only if you create the executor in the same method.
// Otherwise, creating and killing background threads is a matter of your apps strategy.
}

ADK toolkit Android+Arduino store variable issue

I'm writing a program which is supposed to run "forever". The program is Android application for tablet which exchanges data with Arduino. I have already implemented the code for Arduino and Android, and it exchanges data very well. However, after 2 cycles of work, my instance of AdkManager becomes NULL. As I've read before, Android will null variables from time to time because it has limited resources. However here's the problem - the AdkManager has confirmed bug that once it has been closed, it can't be reopened. Thus I can't re-initiate the AdkManager instance and I need to store it somehow. So far I've been using Application extension. The code is below:
MyApplication:
package org.udoo.androidadkdemobidirect;
import android.app.Application;
import android.content.Context;
import android.hardware.usb.UsbManager;
import me.palazzetti.adktoolkit.AdkManager;
/**
* Created by admin on 8/18/16.
*/
public class MyApplication extends Application {
private String someVariable;
public String getSomeVariable() {
return someVariable;
}
public void setSomeVariable(String someVariable) {
this.someVariable = someVariable;
}
public static class sAdkManager{
private static sAdkManager ourInstance = null;
public static sAdkManager getInstance() {
if (ourInstance==null)
ourInstance = new sAdkManager();
return ourInstance;
}
private static AdkManager mAdkManager = null;
public void write(String s){
mAdkManager.writeSerial(s);
}
public String read(){
return mAdkManager.readSerial();
}
public void open(){
mAdkManager.open();
}
public void close(){
mAdkManager.close();
}
public boolean checkNull(){
return mAdkManager==null;
}
public static void init(Context context){
if(mAdkManager==null) {
mAdkManager = new AdkManager((UsbManager) context.getSystemService(Context.USB_SERVICE));
context.registerReceiver(mAdkManager.getUsbReceiver(), mAdkManager.getDetachedFilter());
}
}
private sAdkManager() {
}
}
}
MainActivity:
package org.udoo.androidadkdemobidirect;
import me.palazzetti.adktoolkit.AdkManager;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.usb.UsbManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.TextView;
import android.widget.ToggleButton;
//import org.udoo.androidadkdemobidirect.sAdkManager;
public class MainActivity extends Activity{
// private static final String TAG = "UDOO_AndroidADKFULL";
private static String mAdkManager=null;
private ToggleButton buttonLED;
private TextView distance;
private AdkReadTask mAdkReadTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//
//// register a BroadcastReceiver to catch UsbManager.ACTION_USB_ACCESSORY_DETACHED action
// registerReceiver(mAdkManager.getUsbReceiver(), mAdkManager.getDetachedFilter());
buttonLED = (ToggleButton) findViewById(R.id.toggleButtonLed);
distance = (TextView) findViewById(R.id.textViewIntro);
// mAdkManager.open();
TextView tv = (TextView) findViewById(R.id.ppm);
if (mAdkManager==null){
tv.setText("ADK is null. init()");
mAdkManager = new String ("sometext");
}
else{
tv.setText("ADK is not null.");
}
if (MyApplication.sAdkManager.getInstance().checkNull()) {
distance.setText("Null before init");
MyApplication.sAdkManager.init(this);
}
if (MyApplication.sAdkManager.getInstance().checkNull()) {
distance.setText("Null after init");
}
MyApplication.sAdkManager.getInstance().open();
mAdkReadTask = new AdkReadTask();
mAdkReadTask.execute();
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onDestroy() {
MyApplication.sAdkManager.getInstance().close();
// unregisterReceiver(mAdkManager.getUsbReceiver());
super.onDestroy();
}
// ToggleButton method - send message to SAM3X
public void blinkLED(View v){
if (buttonLED.isChecked()) {
TextView tvdbg = (TextView) findViewById(R.id.ppm);
tvdbg.setText("send 1");
// writeSerial() allows you to write a single char or a String object.
//mAdkManager.writeSerial("1");
MyApplication.sAdkManager.getInstance().write("1");
// mAdkManager.writeSerial("8");
} else {
//mAdkManager.writeSerial("0");
MyApplication.sAdkManager.getInstance().write("0");
}
}
/*
* We put the readSerial() method in an AsyncTask to run the
* continuous read task out of the UI main thread
*/
private class AdkReadTask extends AsyncTask<Void, String, Void> {
private boolean running = true;
public void pause(){
running = false;
}
protected Void doInBackground(Void... params) {
// Log.i("ADK demo bi", "start adkreadtask");
while(running) {
// if (mAdkManager.serialAvailable())
// publishProgress(mAdkManager.readSerial()) ;
publishProgress(MyApplication.sAdkManager.getInstance().read());
}
return null;
}
protected void onProgressUpdate(String... progress) {
distance.setText("You put "+((int)progress[0].charAt(0)-48) + " iqos butts\tRFID OK");
next();
// Log.i(TAG, "received: " + (int)progress[0].charAt(0));
}
}
private void next() {
final Intent intent = new Intent(this, BRActivity.class );
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
mAdkReadTask.pause();
mAdkReadTask = null;
startActivity(intent);
}
},
3000);
}
}
There are just 2 Activities for now - MainActivity and BRActivity. BRActivity is just a view with "return" button which comes back to MainActivity.
Also what I find interesting - I output the readSerial in TextView to see what I got in reader thread. However on cycle#2 i don't get any output to TextView, but Activity still changes to the next one.
[EDIT]
Apparently the problem was solved when the thread was nulling. However, I still don't get the text update, but I magically get to another screen. Please advice.

android development loop problems with timer

i need some help looping a timer in android. I need it to loop 5 times and then stop at 0 on the last run/countdown, but can seems to get it to work. I know it might be a simple.
Any help would be appreciated, thanks to anyone that does help.
package com.project.secondproject;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
private int countdownValue;
private TextView textfield;
private Handler handler;
private boolean Running;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void start(View view){
int countdownValue = 30;
int counter = 0;
Running = true;
textfield = (TextView)findViewById(R.id.Timer);
handler = new Handler();
Runnable runnable = new Runnable(){
#Override
public void run(){
while(Running){
try{
//This controls the interval of the timer. every 1 second
Thread.sleep(1000);}
catch(InterruptedException e){
e.printStackTrace();
}
handler.post(new Runnable(){
#Override
public void run(){
countdownValue -= 1;
textfield.setText(String.valueOf(":" + countdownValue));
if(countdownValue == 1){
Running = false;
}
}
});
}
}
};
new Thread(runnable).start();
}
public void pause(View view){
Running = false;
}
}//End of class
Hope this is what you are looking for. Try this.!
public void run()
{
while(Running){
for (int counter = 5; counter > 0; counter++)
{
System.out.println(" loop..." + counter);
try{Thread.sleep(1000);} // 1 second pause
catch(Exception e){}
}
}

unfortunately has stopped android

I have a problem. When I run my android program I have a error: "unfortunately has stopped android". Why I see this error when I run application? hear is my file:
enter code here
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class SimpleClientActivityActivity extends Activity {
private Socket client;
private PrintWriter printwriter;
private EditText textField;
private Button button;
private String messsage;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//textField = (EditText) findViewById(R.id.editText1); //reference to the text field
button = (Button) findViewById(R.id.button1); //reference to the send button
//Button press event listener
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//messsage = textField.getText().toString(); //get the text message on the text field
//textField.setText(""); //Reset the text field to blank
try {
client = new Socket("10.0.2.2", 4444); //connect to server
printwriter = new PrintWriter(client.getOutputStream(),true);
printwriter.write(messsage); //write the message to output stream
printwriter.flush();
printwriter.close();
client.close(); //closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
I would like to send sms to PC server with my adnroid client
It may be because you are doing network operations on the main thread. Look into your logcat and there will be info, in red.
try this
new Thread(){
#Override
public void run(){
// your onClick code here
}
}.start();
Also you can use AsyncTask for network operations
public class YourTask extends AsyncTask{
private Context context;
private ProgressDialog dialog;
public SplitCueTask(Context context) {
this.context = context;
this.dialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
dialog.setMessage(getResources().getString(R.string.loading));
dialog.show();
}
#Override
protected Boolean doInBackground(Object... objects) {
// you logic here, return result
return someObject.
}
#Override
protected void onPostExecute(Object someObject) {
if (dialog.isShowing())
dialog.dismiss()
// handle result here, post it on UI or something else
}
}
Run task
new YourTask(context).execute();
And dont forget to add INTERNET PERMISSION to AndroidManifest
<uses-permission android:name="android.permission.INTERNET" />

Categories

Resources