Android——子线程刷新UI界面
xml配置文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text="刷新方式:" android:textColor="@color/black" android:textSize="17sp" /> <Spinner android:id="@+id/sp_refresh" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="left|center" android:spinnerMode="dialog" /> </LinearLayout> <!-- 自定义的椭圆视图,需要使用全路径 --> <com.example.myapplication.OvalView android:id="@+id/ov_validate" android:layout_width="match_parent" android:layout_height="150dp" /> </LinearLayout>
item_select.xml文件:
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="40dp" android:singleLine="true" android:gravity="center" android:textSize="17sp" android:textColor="#0000ff" />
OvalView
package com.example.myapplication; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; public class OvalView extends View { private Paint mPaint = new Paint(); // 创建一个画笔对象 private int mDrawingAngle = 0; // 当前绘制的角度 public OvalView(Context context) { this(context, null); } public OvalView(Context context, AttributeSet attrs) { super(context, attrs); mPaint.setColor(Color.RED); // 设置画笔的颜色 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mDrawingAngle += 30; // 绘制角度增加30度 int width = getMeasuredWidth(); // 获得布局的实际宽度 int height = getMeasuredHeight(); // 获得布局的实际高度 RectF rectf = new RectF(0, 0, width, height); // 创建扇形的矩形边界 // 在画布上绘制指定角度的扇形。第四个参数为true表示绘制扇形,为false表示绘制圆弧 canvas.drawArc(rectf, 0, mDrawingAngle, true, mPaint); } }
MainActivity
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; public class MainActivity extends AppCompatActivity { private OvalView ov_validate; // 声明一个椭圆视图对象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ov_validate = findViewById(R.id.ov_validate); initRefreshSpinner(); // 初始化刷新方式的下拉框 } // 初始化刷新方式的下拉框 private void initRefreshSpinner() { ArrayAdapter<String> refreshAdapter = new ArrayAdapter<String>(this,R.layout.item_select, refreshArray); Spinner sp_refresh = findViewById(R.id.sp_refresh); sp_refresh.setPrompt("请选择刷新方式"); // 设置下拉框的标题 sp_refresh.setAdapter(refreshAdapter); // 设置下拉框的数组适配器 sp_refresh.setSelection(0); // 设置下拉框默认显示第一项 // 给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法 sp_refresh.setOnItemSelectedListener(new RefreshSelectedListener()); } private String[] refreshArray = { "主线程调用invalidate", "主线程调用postInvalidate", "延迟3秒后刷新", "分线程调用invalidate", "分线程调用postInvalidate" }; class RefreshSelectedListener implements AdapterView.OnItemSelectedListener { public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { if (arg2 == 0) { // 主线程调用invalidate ov_validate.invalidate(); // 刷新视图(用于主线程) } else if (arg2 == 1) { // 主线程调用postInvalidate ov_validate.postInvalidate(); // 刷新视图(主线程和分线程均可使用) } else if (arg2 == 2) { // 延迟3秒后刷新 ov_validate.postInvalidateDelayed(3000); // 延迟若干时间后再刷新视图 } else if (arg2 == 3) { // 分线程调用invalidate // invalidate不是线程安全的,虽然下面代码在分线程中调用invalidate方法也没报错,但在复杂场合可能出错 new Thread(new Runnable() { @Override public void run() { ov_validate.invalidate(); // 刷新视图(用于主线程) } }).start(); } else if (arg2 == 4) { new fourThread().start(); // 分线程调用postInvalidate // // postInvalidate是线程安全的,分线程中建议调用postInvalidate方法来刷新视图 // new Thread(new Runnable() { // @Override // public void run() { // ov_validate.postInvalidate(); // 刷新视图(主线程和分线程均可使用) // Log.i("444444444444", "run: 111111111111111111111111111111111111111111111111111"); // } // }).start(); } } public void onNothingSelected(AdapterView<?> arg0) {} } public class fourThread extends Thread{ public void run() { ov_validate.postInvalidate(); // 刷新视图(主线程和分线程均可使用) Log.i("444444444444", "run: 111111111111111111111111111111111111111111111111111"); } } }