我想动态更改textview的文本,但如果我想制作一个游戏线程,我需要相同的逻辑,所以我需要在主要的和第二个之间进行通信。
我有文件:
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();
}
}
}
}
我看到的问题是,当我的线程在另一个文件中时,如何使用处理程序更改文本?或者我应该在第一个类中使第二个类静态(当代码变得非常长时,我应该怎么做,它不能都在一个文件中)?
答案 0 :(得分:0)
您可以实施自定义Interface
,以便从主要活动中处理它。
在SampleThread
上:
public interface TextViewChangeListener
{
public void onTextViewChanged(String newName);
}
TextViewChangeListener mListener;
然后在mListener.onTextViewChanged(String newName)
中的任何地方拨打TextView
。请记住首先使用mListener
的实例初始化MainActivity
,否则您将获得空指针异常。您可以在SampleThread
的构造函数中执行此操作,也可以为此创建方法。
在您的活动中,您应该SampleThread.TextViewChangeListener
和override
onTextViewChanged
。
@Override
public void onTextViewChanged(String newName)
{
//MyTextView.setText(newName);
}
修改:未经测试的代码:
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();
}
}
}
}
如果有帮助,请告诉我。
答案 1 :(得分:0)
您可以在Grafika中找到一些示例,它们可以在UI线程中完成大量工作。例如,TextureFromCameraActivity有一对处理程序,一个用于UI线程,一个用于呈现器线程。在onResume()
中,您可以看到主线程通过构造函数将其处理程序传递给渲染器,然后通过方法调用检索渲染器线程的处理程序。
ContinuousCaptureActivity有一个稍微不同的方法,使用也实现回调接口的Handler。处理程序对象作为接口实例传递给CircularEncoder构造函数。公共回调方法在内部使用Handler。
唯一棘手的问题是,如果您将Handler传递出非UI线程。您需要在线程启动之前执行此操作,或使用适当的线程同步操作来避免data races。
您不需要将您的课程放在同一个文件中(除非有人嵌套在另一个文件中,否则您真的不应该这样做)。如果他们在同一个包中,那么默认(包)范围将让他们看到对方。 Grafika的第一个例子使用嵌套/私有类,第二个例子更加分散。
当然,如果你要做的只是从非UI线程提交UI事件,你可以使用Activity.runOnUiThread()。