Search code examples
javaandroidrandomhandlerrunner

My Runner using a Handler is not working on android


Here's what I got so far guys, this is my app, all it does is display a digital clock and move the clock to a new part of the screen every 30 seconds, but it doesn't actually do that last part, here's the code:

public class MainActivity extends Activity {

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 , 30000);
        }
    }; 

@Override
protected void onCreate(Bundle savedInstanceState) {


    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    TextView textView = (TextView) findViewById(R.id.digitalClock);  
    Random r = new Random();

    Thread thread =new Thread(runnable );
    thread.start();

    int x = r.nextInt(350 - 100);
    int y = r.nextInt(800 - 100);

    textView.setX(x);  
    textView.setY(y);
    }

I just cant seem to get this to work, been scanning the internet for about a week now. I think it's got something to do with the "New Thread" but not too sure what.


Solution

  • There's no need to create an extra Runnable instance or your own thread.

    In the onCreate method, all you should do is call setContentView and send an empty message to the handler.

    In the handleMessage method of your Handler instance, set the X and Y of the TextView and post another empty message with a delay.

    Here's an Activity that will do what you want. It uses an AbsoluteLayout to do the absolute positioning of the TextView which is deprecated, but it should demonstrate the Handler bits which are at the core of your question.

    package com.scompt.so16209790;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import android.widget.TextView;
    
    import java.lang.ref.WeakReference;
    import java.util.Random;
    
    public class MainActivity extends Activity {
        private static final Random RANDOM = new Random();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            Handler handler = new RandomMoveHandler((TextView) findViewById(R.id.text_view));
            handler.sendEmptyMessage(0);
        }
    
        // Make the handler subclass static because of this: http://stackoverflow.com/a/11408340/111777
        private static class RandomMoveHandler extends Handler {
            private final WeakReference<TextView> textViewWeakReference;
    
            private RandomMoveHandler(TextView textView) {
                this.textViewWeakReference = new WeakReference<TextView>(textView);
            }
    
            @Override
            public void handleMessage(Message msg) {
                TextView textView = textViewWeakReference.get();
                if (textView == null) {
                    Log.i(TAG, "WeakReference is gone so giving up.");
                    return;
                }
    
                int x = RANDOM.nextInt(350 - 100);
                int y = RANDOM.nextInt(800 - 100);
    
                Log.i(TAG, String.format("Moving text view to (%d, %d)", x, y));
                textView.setX(x);
                textView.setY(y);
    
                //change the text position here
                this.sendEmptyMessageDelayed(0, 3000);
            }
        }
    
        private static final String TAG = MainActivity.class.getSimpleName();
    }
    

    The main layout looks like this:

    <?xml version="1.0" encoding="utf-8"?>
    <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    <TextView
            android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="0px"
        android:layout_y="0px"
        android:text="Hello World, MainActivity"
        />
    </AbsoluteLayout>