Android thread error - android

The thread in my application is giving a weird error on the myThread.start() function specifically the start is wrong the error is "Cannot resolve symbol start" . initially i thought it was a bracket issue but when i adjust them it ends up breaking the OnClicklistner. The thread is suppose just suppose to make the user wait before doing a set text and then the following button will take the user to a website. Can any one see my error?
package com.example.trap.york_hw6;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.TextView;
public class Main3Activity extends AppCompatActivity implements View.OnClickListener {
Button Cheat;
Button NextPage3;
WebView browser3;
#SuppressLint("HandlerLeak")
Handler handler = new Handler() {
public void handleMessage(Message msg) {
TextView statement = (TextView) findViewById(R.id.snitch);
statement.setText("Checking to see if your a cop");
}
;
};
#SuppressLint("HandlerLeak")
Handler handler2 = new Handler() {
public void handleMessage(Message msg) {
browser3.loadUrl("https://www.youtube.com");
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
browser3 = (WebView) findViewById(R.id.webkit3);
browser3.getSettings().setJavaScriptEnabled(true);
browser3.getSettings().setDomStorageEnabled(true);
Cheat = (Button) findViewById(R.id.CC);
NextPage3 = (Button) findViewById(R.id.Next3);
NextPage3.setOnClickListener(this);
Cheat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Runnable r = new Runnable() {
public void run() {
long futureTime = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < futureTime) {
synchronized (this) {
try {
wait(futureTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
handler.sendEmptyMessage(0);
}
;
Thread myThread = new Thread(r);
myThread.start();
};
}
});
final Runnable r2 = new Runnable() {
public void run() {
long futureTime = System.currentTimeMillis() + 7000;
while (System.currentTimeMillis() < futureTime) {
synchronized (this) {
try {
wait(futureTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
handler.sendEmptyMessage(0);
}
;
Thread myThread2 = new Thread(r2);
myThread2.start();
};
}
public void onClick(View v) {
Intent i = new Intent(this, Main4Activity.class);
i.putExtra("value", "I got this from MainActivity2");
i.putExtra("value1", 5);
startActivityForResult(i, 3);
}
}

You are starting thread inside wrong block. Try the code below .
final Runnable r2 = new Runnable() {
public void run() {
long futureTime = System.currentTimeMillis() + 7000;
while (System.currentTimeMillis() < futureTime) {
synchronized (this) {
try {
wait(futureTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
handler.sendEmptyMessage(0);
};
};
Thread myThread2 = new Thread(r2);
myThread2.start();
AND
Cheat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Runnable r = new Runnable() {
public void run() {
long futureTime = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < futureTime) {
synchronized (this) {
try {
wait(futureTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
handler.sendEmptyMessage(0);
};
};
Thread myThread = new Thread(r);
myThread.start();
}
});

You can not initialise and start Runnable inside its block.
You can write like this.
Cheat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Runnable r = new Runnable() {
public void run() {
long futureTime = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < futureTime) {
synchronized (this) {
try {
wait(futureTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
handler.sendEmptyMessage(0);
}
};
Thread myThread = new Thread(r);
myThread.start();
}
});
and second one
final Runnable r2 = new Runnable() {
public void run() {
long futureTime = System.currentTimeMillis() + 7000;
while (System.currentTimeMillis() < futureTime) {
synchronized (this) {
try {
wait(futureTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
handler.sendEmptyMessage(0);
}
};
Thread myThread2 = new Thread(r2);
myThread2.start();
Suggestion : Also i seen your onClick method, i suggest you check clicked button's id before doing any action like. Because if you have multiple buttons having OnClickListener referring to current class, you will need to check.
public void onClick(View v) {
switch (v.getId()){
case R.id.Next3:
Intent i = new Intent(this, Main4Activity.class);
i.putExtra("value", "I got this from MainActivity2");
i.putExtra("value1", 5);
startActivityForResult(i, 3);
break;
}
}

Related

Changing image src over time

Im pretty new to android and I'm trying to make an imagebutton in android studio that changes images at set inervals. I tried to just use wait and put it into a different thread but that doesn't seem to work. All I want if for the image to change while also still allowing for a mp3 to be played whilst doing so.
Runnable r = new Runnable() {
#Override
public void run()
{
synchronized (this)
{
try
{
wait(1000);
ank.setImageResource(R.drawable.shank2);
wait(1000);
ank.setImageResource(R.drawable.shank3);
wait(1000);
ank.setImageResource(R.drawable.shank4);
wait(1000);
ank.setImageResource(R.drawable.shank5);
}
catch (Exception e) {}
}
}
};
Thread myThread = new Thread(r);
myThread.start();
Simple way:
public void changeImages() {
Handler uiHandler = new Handler();
uiHandler.postDelayed(new Runnable {
#Override
public void run() {
ank.setImageResource(R.drawable.shank1);
}
}, 1000);
uiHandler.postDelayed(new Runnable {
#Override
public void run() {
ank.setImageResource(R.drawable.shank2);
}
}, 2000);
...
}
Better way:
public void changeImages() {
int[] images = new int[] { R.drawable.shank1, R.drawable.shank2 ... }
long delay = 1000;
Handler uiHandler = new Handler();
for (int imageRes : images) {
uiHandler.postDelayed(new Runnable {
#Override
public void run() {
ank.setImageResource(imageRes);
}
}, delay);
delay += 1000;
}
}
The best way
final Handler uiHandler = new Handler();
final Queue<Integer> queue = new LinkedBlockingQueue<>();
void changeImages() {
queue.add(R.drawable.shank1);
queue.add(R.drawable.shank2);
...
loopImages();
}
void loopImages() {
if (!queue.isEmpty()) {
uiHandler.postDelayed(new Runnable() {
#Override
public void run() {
ank.setImageResource(queue.poll());
}
}, 1000);
}
}

android, disabling the save button for one hour

i am trying to disable the save button for exactly 1 hour, before the user can save data again. I have come up with some code but since i am still really new to programming i am kind of stuck and any help would be appritiated.
The problem is the button does not lock when i click save.
public void AddData(){
gumb_poslji.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Activity activity = getActivity();
Calendar calander = Calendar.getInstance();
Integer cDay = calander.get(Calendar.DAY_OF_MONTH);
Integer cHour = calander.get(Calendar.HOUR_OF_DAY);
Integer cDayOfTheWeek = calander.get(Calendar.DAY_OF_WEEK)-1;
Integer cMonth = calander.get(Calendar.MONTH)+1;
int seekBarProgressValue = seekBar.getProgress();
String strI = String.valueOf(seekBarProgressValue);
String poslji_data = strI;
boolean pregled_vnosa = myDb.insertData(poslji_data,cHour,cDay,cDayOfTheWeek,cMonth);
if (pregled_vnosa==true)
Toast.makeText(activity, "Vnos uspešen",Toast.LENGTH_LONG).show();
else
Toast.makeText(activity, "Vnos neuspešen!!!",Toast.LENGTH_LONG).show();
}
});
gumb_poslji.setEnabled(true);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(3600000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
gumb_poslji.setEnabled(false);
}
});
}
}).start();
}
Handler mHandler= new Handler();
static Runnable mUpdateTimeTask = new Runnable() {
public void run() {
gumb_poslji.setEnabled(false);
mHandler= .removeCallbacks(mUpdateTimeTask);
}
};
mHandler.postDelayed(this, 3600000);

Using handler to change ui, still "only the original thread that created a view hierarchy can touch its views." error

I have two threads, two handlers. From thread i check a random number and send result to handle to update ui. But i am getting the error "only the original thread that created a view hierarchy can touch its views.". I searched some articles, they tell to use handler. I am doing that, yet can not avoid the errors.
After some checking, I found that it crashes when A sends the result. In case of B, it works
Also, can i use one handler for two thread?
public class MainActivity extends Activity implements View.OnClickListener{
Button start;
TextView status_B, status_A;
Boolean isRunning;
Thread Athread, Bthread;
int a, b;
Handler a_Handler, b_Handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initialize variables
start = (Button) findViewById(R.id.button);
start.setOnClickListener(this);
status_B = (TextView) findViewById(R.id.textView);
status_A = (TextView) findViewById(R.id.textView1);
a_Handler = new Handler() {
public void handleMessage(Message msg)
{
int number = msg.getData().getInt("number");
String winner = msg.getData().getString("winner");
start.setEnabled(true);
isRunning = false;
status_A.setText(winner + number);
}
};
b_Handler = new Handler() {
public void handleMessage(Message msg)
{
int number = msg.getData().getInt("number");
String winner = msg.getData().getString("winner");
start.setEnabled(true);
isRunning = false;
status_B.setText(winner + number);
}
};
}
#Override
protected void onStart() {
super.onStart();
isRunning = false;
}
#Override
public void onClick(View v) {
start.setEnabled(false);
status_B.setText("Guessing...");
if (!isRunning)
{
Athread = new Thread(new Runnable() {
#Override
public void run() {
while (isRunning)
{
try
{
Athread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
a = (int) (Math.random()*1000);
System.out.println("a "+ a);
if(a%7 == 0) {
isRunning = false;
Bundle bundle = new Bundle();
bundle.putString("winner", "A");
bundle.putInt("number", a);
Message msg = a_Handler.obtainMessage();
msg.setData(bundle);
a_Handler.handleMessage(msg);
}
}
}
});
Bthread = new Thread(new Runnable() {
#Override
public void run() {
while(isRunning)
{
try
{
Bthread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
b = (int) (Math.random()*1000);
System.out.println("b "+ b);
if(b%7 == 0) {
isRunning = false;
Bundle bundle = new Bundle();
bundle.putString("winner", "B");
bundle.putInt("number", b);
Message msg = b_Handler.obtainMessage();
msg.setData(bundle);
b_Handler.sendMessage(msg);
}
}
}
});
isRunning = true;
Athread.start();
Bthread.start();
}
}
}
You need put your code to modify views on UI thread:
a_Handler = new Handler() {
public void handleMessage(Message msg)
{
final int number = msg.getData().getInt("number");
final String winner = msg.getData().getString("winner");
runOnUiThread(new Runnable() {
#Override
public void run() {
start.setEnabled(true);
status_A.setText(winner + number);
}
});
isRunning = false;
}
};
b_Handler = new Handler() {
public void handleMessage(Message msg)
{
final int number = msg.getData().getInt("number");
final String winner = msg.getData().getString("winner");
runOnUiThread(new Runnable() {
#Override
public void run() {
start.setEnabled(true);
status_B.setText(winner + number);
}
});
isRunning = false;
}
};

How to set Delay for loop in android?

I am trying to display a multiplication table with delay. My code is working fine but I am not able to implement the delay.
Here is My code:
tableButton1 = (Button) findViewById(R.id.Button1);
tableButton1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
str = tableButton1.getText().toString();
a = Integer.parseInt(str);
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 10; i++){
sb.append(a + " x " + i + " = " + i * a+ "\n");
}
s = String.valueOf(sb);
Intent intent=new Intent(getApplicationContext(),TextViewActivity.class);
intent.putExtra("MA", s);
startActivity(intent);
}
});
//Toast.makeText(getApplicationContext(), "Hi" +ss, 222).show();
}
});
Any answer is appreciable.
Thank's in advance
Updated-code:- This code is working with help of #theLittleNaruto
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class TestActivity extends Activity{
Button tableButton1;
TextView txtView;
int value = 0;
static int count = 0;
Handler handle = new Handler();
StringBuilder sb = new StringBuilder();
Runnable r = new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "onrunnable" +sb, 222).show();
// TODO Auto-generated method stub
updateTable();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.text_display);
Toast.makeText(getApplicationContext(), "oncreate" , 222).show();
txtView = (TextView) findViewById(R.id.outputTXT);
tableButton1 = (Button) findViewById(R.id.seven);
tableButton1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "onclick" , 222).show();
value= Integer.parseInt(tableButton1.getText().toString());
updateTable();
}
});
}
public void updateTable(){
count+=1000;
if(count==11000){
//Toast.makeText(getApplicationContext(), "onupdate" , 222).show();
count = 0;
value=0;
handle.removeCallbacks(r);
sb.setLength(0);
}else{
sb.append(value + " x " + count/1000 + " = " + count/1000 * value+ "\n");
handle.postDelayed(r, 1000);
// Toast.makeText(getApplicationContext(), "onupdateElse" +sb, 222).show();
txtView.setText(sb);
}
}
}
Thank you all the supporters and their best try to help me
Why dont you try what the other is saying with this little effort ;)
public class TestActivity extends Activity{
int value = 0;
static int count = 0;
Handler handle = new Handler();
StringBuilder sb = new StringBuilder();
Runnable r = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
updateTable();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.oaot_get);
tableButton1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
value= Integer.parseInt(tableButton1.getText().toString());
updateTable();
}
});
}
public void updateTable(){
count+=1000;
if(count==11000){
count = 0;
value=0;
handle.removeCallbacks(r);
sb.setLength(0);
}else{
sb.append(value + " x " + count/1000 + " = " + count/1000 * value+ "\n");
handle.postDelayed(r, 1000);
}
}
}
Try this
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
str = tableButton1.getText().toString();
a = Integer.parseInt(str);
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 10; i++){
sb.append(a + " x " + i + " = " + i * a+ "\n");
}
}, 5000);
s = String.valueOf(sb);
Intent intent=new Intent(getApplicationContext(),TextViewActivity.class);
intent.putExtra("MA", s);
startActivity(intent);
Add a handler(). Replace your onClick code with:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
str = tableButton1.getText().toString();
a = Integer.parseInt(str);
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 10; i++)
{
sb.append(a + " x " + i + " = " + i * a+ "\n");
}s=String.valueOf(sb);
Intent intent=new Intent(getApplicationContext(),TextViewActivity.class);
intent.putExtra("MA", s);
startActivity(intent);
}
}, 5000);
Repalce 5000 with the time you want it to be delayed for in milliseconds
Add a Handler that will execute your runnable:
Runnable runnable = new Runnable() {
#Override
public void run() {
str = tableButton1.getText().toString();
a = Integer.parseInt(str);
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 10; i++){
sb.append(a + " x " + i + " = " + i * a+ "\n");
//--ADDED stuff here------------------------------------------------------------
try {
//Sleep will suspend your Thread for 500 miliseconds and resumes afterwards
Thread.sleep(500);
} catch (InterruptedException e) {
Log.e("error, Thread interrupted", e);
}
}
s = String.valueOf(sb);
Intent intent=new Intent(getApplicationContext(),TextViewActivity.class);
intent.putExtra("MA", s);
startActivity(intent);
}
Handler handler = new Handler();
//this will execute your runnable after 500 milliseconds
handler.postDelayed(runnable, 500);
You can use that :
public class Scheduler {
// DATA
private OnScheduleTimeListener mListener;
private Handler mHandler;
private int mInterval; // Between each executions
private static final int DELAY = 100; // before first execution
private boolean mIsTimerRunning;
public static interface OnScheduleTimeListener {
public void onScheduleTime();
}
public Scheduler(int interval) {
super();
mInterval = interval;
mHandler = new Handler();
}
private final Runnable mRunnable = new Runnable() {
#Override
public void run() {
// Do stuff
mListener.onScheduleTime();
// Repeat
mHandler.postDelayed(mRunnable, mInterval);
}
};
public void setOnScheduleTimeListener(OnScheduleTimeListener listener) {
mListener = listener;
}
public void startTimer() {
mIsTimerRunning = true;
mHandler.postDelayed(mRunnable, DELAY);
}
public void stopTimer() {
mIsTimerRunning = false;
mHandler.removeCallbacks(mRunnable);
}
public boolean isTimerRunning() {
return mIsTimerRunning;
}
}
Now to use it :
private void startTimer() {
mScheduler = new Scheduler(INTERVAL);
mScheduler.setOnScheduleTimeListener(new OnScheduleTimeListener() {
#Override
public void onScheduleTime() {
Log.d(TAG, "update");
});
mScheduler.startTimer();
}
private void stopTimer(){
if (mScheduler != null && mScheduler.isTimerRunning()) {
mScheduler.stopTimer();
mScheduler = null;
}
}
Try this....
do {
try {
try {
response_req_sequence = SimpleHttpClient
.sendresponseSequReqRes(response_send_order);
System.out.println("response of sequence request"
+ response_req_sequence);
System.out.println(" i ma in thread");
if (response_req_sequence.trim().length() != 0) {
System.out.println("response in result of sequ"+ response_req_sequence);
break;
}
Thread.sleep(10000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (Exception e) {
// TODO: handle exception
}
} while (response_req_sequence.trim().equalsIgnoreCase(""));
This is working fine for me. you can customize according to you.

Start Timer on activity create method android

i need to display message to application user when admin pushes message on browser. for that i implemented a timer so that it displays a message to user on application start. timer keeps running to get as message once in 20 minutes if a new message is pushed. my timer is working fine but on button click.
I want my timer to start as soon as activity loads.
Is this proper way to display a message? (it is like banner)
How resource consuming is a timer?
Timer Task
class secondTask extends TimerTask {
#Override
public void run() {
TestBannerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
fl.setVisibility(View.VISIBLE);
long millis = System.currentTimeMillis() - starttime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
text2.setText(String.format("%d:%02d", minutes,
seconds));
}
});
}
};
button click event
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Button b = (Button) v;
if (b.getText().equals("stop")) {
timer.cancel();
timer.purge();
b.setText("start");
} else {
starttime = System.currentTimeMillis();
timer = new Timer();
timer.schedule(new secondTask(), 8000, 1200000);
b.setText("stop");
}
}
});
you can use this code:
package packagename.timerService;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
public class TimerService extends Service{
public static final String BROADCAST_TIMER_ACTION = "packagename.timerService.TimerService";
private final Handler handler = new Handler();
private final Handler updateUIHandler = new Handler();
Intent intent;
int time = 0;
private int durationTime = 0;
private int starDate;
private int currentDate;
private Date startTaskDate;
private String taskComment;
#Override
public void onCreate() {
// Called on service created
intent = new Intent(BROADCAST_TIMER_ACTION);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
handler.removeCallbacks(sendUpdatesToUI);
handler.post(sendUpdatesToUI); //post(sendUpdatesToUI);
starDate = Calendar.getInstance().get(Calendar.DATE);
durationTime = 0;
startTaskDate = new Date();
}
} catch (Exception e) {}
return START_STICKY;
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
try{
displayLoggingInfo();
time ++;
durationTime ++;
handler.postDelayed(this, 60 * 1000); // 1 minute
}catch (Exception e) { }
}
};
private Runnable sendUpdatesToUIOnResume = new Runnable() {
public void run() {
displayLoggingInfoForOnResume();
}
};
private void displayLoggingInfoForOnResume() {
try{
currentDate = Calendar.getInstance().get(Calendar.DATE);
intent.putExtra("changeDate", String.valueOf(false));
intent.putExtra("time", String.valueOf(time == 0 ? time : time - 1 ));
sendBroadcast(intent);
} catch (Exception e) { }
}
private void displayLoggingInfo() {
try{
currentDate = Calendar.getInstance().get(Calendar.DATE);
intent.putExtra("changeDate", String.valueOf(false));
intent.putExtra("durationTime", String.valueOf(durationTime));
intent.putExtra("time", String.valueOf(time));
sendBroadcast(intent);
}catch (Exception e) {
// TODO: handle exception
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
try {
handler.removeCallbacks(sendUpdatesToUI);
updateUIHandler.removeCallbacks(sendUpdatesToUIOnResume);
durationTime = 0;
time = 0;
super.onDestroy();
} catch (Exception e) { }
}
#Override
public boolean stopService(Intent name) {
handler.removeCallbacks(sendUpdatesToUI);
updateUIHandler.removeCallbacks(sendUpdatesToUIOnResume);
durationTime = 0;
time = 0;
return super.stopService(name);
}
}

Categories

Resources