سؤال

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.

هل كانت مفيدة؟

المحلول

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>

نصائح أخرى

I'm a little bit curious about your solution, I'd like to not use Thread in Android app, you can just trigger Handler instead. Here is example

Handler handler = new Handler() {
@Override public void handleMessage(Message msg) {
// your jobs
} };

and then in activity you can just postAtTime method where you need.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top