使用Timer的运行时错误 - Android

时间:2015-02-15 12:57:41

标签: java android timer runtime

我正在使用此处给出的Timer示例:https://stackoverflow.com/a/2535778/4549769 但是我在执行这一行时遇到运行时错误(我已经评论了所有其他的调试): intensityTextView.setText(String.valueOf(_intensity)); 我知道我需要以某种方式传递UI,但不知道如何。

这是代码



package hanan.smartlight;

import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Timer;
import java.util.TimerTask;


public class Main extends ActionBarActivity {
  //  private SeekBar intensitySeekBar;
    private int _intensity=0;
    private String _ServerResponse="";
    private boolean led_state=false;
    private int repeatTimeMs=1000;
    private int delayStartingTimeMs = 5000; // 5 seconds by default, can be changed later
    TextView intensityTextView;
    SeekBar intensitySeekBar;
    Switch ledSwitch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        intensityTextView = (TextView) findViewById(R.id.intensityValue);
        intensitySeekBar = (SeekBar) findViewById(R.id.intensitySeekBar);
        ledSwitch = (Switch) findViewById(R.id.ledSwitch);


        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask()
        {
            public void run()
            {
                setControl();  // display the data
            }
        }, delayStartingTimeMs, repeatTimeMs);

        //   Timer timer = new Timer();
     //   MyTimerTask myTimerTask = new MyTimerTask();

     //   timer.schedule(myTimerTask, delayStartingTimeMs, repeatTimeMs);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void SyncWithServer(){

    }

    public void setControl() {
        String url = "http://smartlight.gear.host/getControlsFromDB.php"; //url for server
        new UploadToServer().execute(url); //send the request

        int ledS = 0;
        int intS = 0;
        String s1 = "";
        String s2 = "";
        if (_ServerResponse.length() > 3) {
            try {
                s1 = _ServerResponse.substring(3, 6);
            } catch (Exception e) {
                return;
            }
            try {
                s2 = _ServerResponse.substring(9, _ServerResponse.length() - 2);
            } catch (Exception e) {
                return;
            }
            try {
                ledS = Integer.parseInt(s1);
            } catch (NumberFormatException e) {
                return;
            }
            try {
                intS = Integer.parseInt(s2);
            } catch (NumberFormatException e) {
                return;
            }

            if (ledS == 255)
                led_state = true;
            else if (ledS == 254)
                led_state = false;

            if (intS >= 0 && intS <= 100)
                _intensity = intS;
        }

          intensityTextView.setText(String.valueOf(_intensity));
      //  intensityTextView.setText("Test");
//        intensitySeekBar.setProgress(_intensity);
 //       ledSwitch.setChecked(led_state);
       // setValuesToDB();
    }


    public class UploadToServer extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... urls) {
            String response = "";
            for (String url : urls) {
                DefaultHttpClient client = new DefaultHttpClient();
                HttpGet httpGet = new HttpGet(url);
                try {
                    HttpResponse execute = client.execute(httpGet);
                    InputStream content = execute.getEntity().getContent();

                    BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
                    String s = "";
                    while ((s = buffer.readLine()) != null) {
                        response += s;
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (!(response == null || response.equals(" ")))
                _ServerResponse = response;

            return response;
        }

    }

}
&#13;
&#13;
&#13;

&#13;
&#13;
02-15 15:18:57.079    8345-8345/hanan.smartlight E/﹕ appName=hanan.smartlight, acAppName=/system/bin/surfaceflinger
02-15 15:18:57.079    8345-8345/hanan.smartlight E/﹕ 0
02-15 15:19:01.464    8345-8388/hanan.smartlight E/AndroidRuntime﹕ FATAL EXCEPTION: Timer-0
    Process: hanan.smartlight, PID: 8345
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6669)
            at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1005)
            at android.view.ViewGroup.invalidateChild(ViewGroup.java:4548)
            at android.view.View.invalidate(View.java:11134)
            at android.view.View.invalidate(View.java:11083)
            at android.widget.TextView.checkForRelayout(TextView.java:7201)
            at android.widget.TextView.setText(TextView.java:4283)
            at android.widget.TextView.setText(TextView.java:3722)
            at android.widget.TextView.setText(TextView.java:3697)
            at hanan.smartlight.Main.setControl(Main.java:123)
            at hanan.smartlight.Main$1.run(Main.java:48)
            at java.util.Timer$TimerImpl.run(Timer.java:284)
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:0)

在textview上使用post()方法。 Runnable将在用户界面线程上运行。这是如何在TimerTask的run方法中更新textview的示例。

public class MainActivity extends ActionBarActivity {


    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);

        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {

            @Override
            public void run() {
                textView.post(new Runnable() {

                    @Override
                    public void run() {
                        textView.setText("Arun");
                    }
                });
            }
        }, 3000, 3000);

    }
}

在您的情况下,您可以添加

intensityTextView.post(new Runnable() {

    @Override
    public void run() {
        intensityTextView.setText(String.valueOf(_intensity));
    }
});

答案 1 :(得分:0)

Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask()
    {
        public void run()
        {
            mHandler.obtainMessage(1).sendToTarget();

        }
    }, delayStartingTimeMs, repeatTimeMs);

public Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
    setControl(); //this is where textView gets Updated
}

mHandler必须在主线程中!