I have a very simple test application I'm making, and to set the seekBar's position I'm using a runnable. Although I have very little experience with actually working with a runnable.
public class MySpotify extends Activity implements Runnable {
private SeekBar progress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spotify_app);
myProgress = (SeekBar) findViewById(R.id.myBar);
}
#Override
public void run() {
myProgress.setProgress(25);
}
}
If I move myProgress.setProgress(25); into the onCreate then it works. But I want it to be set off in the runnable. Any ideas?
You need to post() a Runnable to a Thread for it to execute. Try calling post(this); inside onCreate().
Try
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spotify_app);
myProgress = (SeekBar) findViewById(R.id.myBar);
myProgress.post(new Runnable()
{
public void run()
{
myProgress.setProgress(25);
}
});
}
You need something to run the post() method on
You can start the run method by just calling run();
Be aware that it will execute on the main thread.
Also be aware that it will run only once since there is no loop.
if you want to update while doing something else you sjould create a new thread.
example:
public class MySpotify extends Activity{
private SeekBar myProgress; //I asume it is call "myProgress" instead of "progress"
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spotify_app);
myProgress = (SeekBar) findViewById(R.id.myBar);
ThreadExample example = new ThreadExample();
example.start();
/* Start a new thread that executes the code in the thread by creating a new thread.
* If ou call example.run() it will execute on the mainthread so don't do that.
*/
}
private class ThreadExample extends Thread{
public void run() {
myProgress.setProgress(25);
}
}
}
Related
Can someone tell me why this doesn't work? I am trying to figure out how to use thread/runnable. Thread doesnt do much but just to loop and let the main thread know to update the text. I dont know what I missed, the centertext doesnt update. Thanks so much.
public class MainActivity extends AppCompatActivity {
TextView centerText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final SysTimeObj sysTimeObj = new SysTimeObj();
centerText = findViewById(R.id.centerText);
Handler stHandler = new Handler(getMainLooper()){
#Override
public void handleMessage(#NonNull Message msg) {
super.handleMessage(msg);
centerText.setText("thread updated");
}
};
startThread(sysTimeObj, stHandler);
}
public void startThread(SysTimeObj sysTimeObj, Handler handler){
clockThread rc = new clockThread(sysTimeObj, handler);
Thread t1 = new Thread(rc);
t1.start();
}
}
public class clockThread implements Runnable {
//private String sysTime;
private Handler handler;
SysTimeObj sysTimeObj;
public clockThread(SysTimeObj sysTimeObj, Handler mHandler){
//sysTime = GregorianCalendar.getInstance().getTime().toString();
this.sysTimeObj = sysTimeObj;
handler = mHandler;
}
#Override
public void run() {
sysTimeObj.setTime();
handler.postDelayed(this, 100);
}
}
You want to do something on the Main/UI Thread after a certain amount of time ? On Android, you don't need a new thread for that.
The Main Thread has a message queue that you can Post to. That message queue is emptied on a regular basis. Posted messages can be configured to be executed at a later time (which is what you seem to want).
To post messages, you need to create a Handler for the target thread. This Handler will let you send messages to that thread. Then, Post a Runnable to that thread using one of the posting methods availlable (here, postDelayed).
You'll end with something like this :
public class MainActivity extends AppCompatActivity {
private TextView yourTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
yourTextView = findViewById(R.id.yourTextView);
Handler handler = new Handler(getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
yourTextView.setText("Updated after 100 ms");
}
}, 100);
}
}
If threads is really what you want, I suggest you look at AsyncTasks. You might also want to look at the official documentation about Process and Threads on Android Developpers.
I am trying to get a simple Runnable to execute some code every few seconds, but although I can get it to execute, I cant get it to stop. The code below shows 2 calls startDbChecking() and stopDbChecking(), I have just placed them in the code block to show what I'm attempting - not how the code is set up.
public class MainActivity extends TabActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startDbChecking(); // will run this no problem
stopDbChecking(); // but will not stop
}
public void startDbChecking() {
handler.post(runnableCode);
}
public void stopDbChecking() {
handler.removeCallbacks(runnableCode);
}
private Runnable runnableCode = new Runnable() {
#Override
public void run() {
// Do something here on the main thread
System.out.println("OK");
handler.postDelayed(runnableCode, 2000);
}
};
}
Try this in your Activity: to stop the runnable
protected void onStop() {
super.onStop();
handler.removeCallbacks(runnableCode);
}
I want to change dynamically the text of a textview, but I will need the same logic if I want to make a game thread, so I need to make the communication between the main one and the second one.
I have the files :
MainActivity
public class MainActivity extends ActionBarActivity {
public static Handler mHandler;
Runnable thread = new SampleThread();
TextView txt1 = (TextView) findViewById(R.id.txt1);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
//hiding status bar
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
setContentView(R.layout.activity_main);
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
// i want to change the text of txt1 here
}
};
new Thread(thread).start();
}
}
SampleThread
package com.example.katsar0v.myapplication;
import android.util.Log;
/**
* Created by Katsar0v on 1/21/2015.
*/
public class SampleThread implements Runnable {
#Override
public void run() {
int two = 0;
while(two<10) {
two++;
try {
Thread.sleep(1000);
//instead of logging, i want to send the text to main UI
Log.d("MSG", String.valueOf(two + "sec"));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
The problem I see is, how do I change the text with the handler, when my thread is in another file? Or should I make the second class static within the first one (and what should I do when the code gets really long, it can't be all in one file)?
You could implement a custom Interface in order to handle it from your main activity.
On your SampleThread:
public interface TextViewChangeListener
{
public void onTextViewChanged(String newName);
}
TextViewChangeListener mListener;
Then call mListener.onTextViewChanged(String newName) wherever you want to have the new name in your TextView. Remember to initialize mListener with an instance of your MainActivity first, otherwise you will get a null pointer exception. You can do that either in the constructor of SampleThread or by creating a method for the purpose.
In your activity you should implement SampleThread.TextViewChangeListener and override the onTextViewChanged.
#Override
public void onTextViewChanged(String newName)
{
//MyTextView.setText(newName);
}
Edit: untested code:
MainActivity:
public class MainActivity extends ActionBarActivity implements SampleThread.TextViewChangeListener {
#Override
public void onTextViewChanged(Message msg)
{
// process incoming messages here
// i want to change the text of txt1 here
}
public static Handler mHandler;
Runnable thread = new SampleThread(this);
TextView txt1 = (TextView) findViewById(R.id.txt1);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
//hiding status bar
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
setContentView(R.layout.activity_main);
new Thread(thread).start();
}
}
SampleThread:
package com.example.katsar0v.myapplication;
import android.util.Log;
/**
* Created by Katsar0v on 1/21/2015.
*/
public class SampleThread implements Runnable
{
public interface TextViewChangeListener
{
public void onTextViewChanged(Message msg);
}
public SampleThread(TextViewChangeListener mListener)
{
this.mListener = mListener;
}
TextViewChangeListener mListener;
#Override
public void run() {
int two = 0;
while(two<10) {
two++;
try {
Thread.sleep(1000);
mListener.onTextViewChanged(String.valueOf(two + "sec"));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Let me know if that helped.
You can find some examples in Grafika, which does a lot of work off the UI thread. For example, TextureFromCameraActivity has a pair of handlers, one for the UI thread, one for the renderer thread. In onResume() you can see the main thread passing its handler to the renderer through a constructor, then retrieving the renderer thread's handler with a method call.
ContinuousCaptureActivity has a slightly different approach, using a Handler that also implements a callback interface. The handler object is passed to the CircularEncoder constructor as an interface instance. The public callback methods use the Handler internally.
The only tricky bit is if you're passing a Handler out of the non-UI thread. You either need to do it before the thread starts, or use appropriate thread synchronization operations to avoid data races.
You don't need to have your classes in the same file (and you really shouldn't unless one is nested inside the other). If they're in the same package then the default (package) scope will let them see each other. The first example from Grafika uses nested / private classes, the second example is more spread out.
Of course, if all you're trying to do is submit UI events from a non-UI thread, you can just use Activity.runOnUiThread().
Is it possible to create a background thread using andriodannotations thats starts in one activity and finish in another activity.
here is what i thought migh have worked
ActivityA
public static LoadingDialog LoadingScreen = new LoadingDialog();
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//.....
LoadingScreen.CreateDialog(context);
}
Background Class
public class LoadingDialog
{
private Dialog loader_dialog;
#Background
public void CreateDialog(Context mContext)
{
loader_dialog = new Dialog(mContext,android.R.style.Theme_Black_NoTitleBar_Fullscreen);
loader_dialog.setContentView(R.layout.loading_screen);
loader_dialog.show();
}
public void Remove()
{
loader_dialog.dismiss();
}
}
the dialog displays correctly but when I finish() activityA to start activityB the thread appears to be killed to and i get a black screen. Any help on this would be much appreciated.
I trying to make my textView appear in different place of the screen every minute or two (delay is not important). I've seen people are suggesting I use runOnUiThread to make a timer repeat the random function and the update the UI.
I'm really struggling getting my head around these different threads, just wondering if anyone could give me an example? Or should I research using something different?
Public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.digitalClock1);
Random r = new Random();
int x = r.nextInt(350 - 100);
int y = r.nextInt(800 - 100);
textView.setX(x);
textView.setY(y);
}
Try this method
public void doInback()
{
handler.postDelayed(new Runnable() {
#Override
public void run()
{
// TODO Auto-generated method stub
// Try the code that you want to repeat
doInback();
}
}, 1000);
}
just call the method where you want to use.
Create the runnable and the handler below
private Runnable runnable = new Runnable(){
#Override
public void run() {
handler.sendEmptyMessage(0);
}
};
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
//change the text position here
this.postDelayed(runnable , TIME_OUT_MS);
}
};
The TIME_OUT_MS is the time out you want in milliseconds.
And put this on the OnCreate() method of the activity
Thread thread =new Thread(runnable );
thread.start();