很久没有写Blog啦,现在写的这个是前段时间遇到的一种思路。
有这么一个需求,你必须得在一个对象类里面操作子线程,然后把子线程产生的数据发送到主线程,并更新UI。
方法有很多,我采用的是用接口来传递数据。
子线程所在类
/**
* Created by Virczz on 2016/5/13.
*/
public class TestNormal {
public TestNormal(MainActivity context) {
try {
if (context != null) {
mCallback = context;
}
} catch (Exception e) {
throw new ClassCastException(this.toString() + " must implement DbCallback");
}
}
/**
* @param <T> 任意的数据类型
*/
public interface DbCallback<T> {
void call(String tag, @Nullable T t);//通过tag标识是谁在调用这个数据,t就是具体的数据
}
private DbCallback mCallback;
public void test() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
mCallback.call("TEST", new RuntimeException("这里做一个异常测试"));
mCallback.call("String", "这个是String类型的调用");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
这个就是对象类,在里面的
test() 就是子线程及其模拟的耗时操作。
DbCallback<T> 接口类是用来传递数据的。
Activity实现
<span style="font-size:12px;">public class MainActivity extends AppCompatActivity implements TestNormal.DbCallback {
private TextView mText1;
private TextView mText2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(android.R.id.button1);
mText1 = (TextView) findViewById(android.R.id.text1);
mText2 = (TextView) findViewById(android.R.id.text2);
final TestNormal testNormal = new TestNormal(this);
if (button != null) {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testNormal.test();// 调用子线程
}
});
}
}
@Override
public void call(String tag, @Nullable final Object o) {
switch (tag) {
case "TEST":
if (o instanceof RuntimeException) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mText1.setText(((RuntimeException) o).getLocalizedMessage());
}
});
}
break;
case "String":
if (o instanceof String) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mText2.setText(((String) o));
}
});
}
break;
}
}
}</span>
在接口的实现方法
call(String tag, @Nullable final Object o) 中,通过判断
tag 来识别数据,然后想要更新UI的时候,一定要调用
runOnUiThread(new Runnable() {...}); 方法。
布局文件
<span style="font-size:12px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="wheelview.text.com.testcallback.MainActivity">
<Button
android:text="测试"
android:id="@android:id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</LinearLayout></span>
这样,就实现了在对象类中的子线程中,通过接口更新UI的操作。