andriod 错误:Only the original thread that created a view hierarchy can touch its views——Handler的使用
package com.example.yanlei.myapplication; import android.media.MediaMetadataRetriever; import android.media.MediaPlayer; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.content.pm.ActivityInfo; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; import android.widget.VideoView; import android.app.Activity; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.SeekBar; import android.widget.Toast; import android.widget.VideoView; import android.widget.SeekBar.OnSeekBarChangeListener; import java.io.File; import java.util.HashMap; import android.os.Handler;
private Handler handler = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); seekBar = (SeekBar) findViewById(R.id.seekBar); // 为进度条添加进度更改事件 seekBar.setOnSeekBarChangeListener(change); //创建属于主线程的handler handler = new Handler(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | protected void play( int msec) { Log.i(TAG, " 获取视频文件地址" ); String path = et_path.getText().toString().trim(); File file = new File(path); if (!file.exists()) { Toast.makeText( this , "视频文件路径错误" , 0 ).show(); return ; } Log.i(TAG, "指定视频源路径" ); vv_video.setVideoPath(file.getAbsolutePath()); Log.i(TAG, "开始播放" ); vv_video.start(); // 按照初始位置播放 vv_video.seekTo(msec); // 设置进度条的最大进度为视频流的最大播放时长 final int time = getTimeLong(file.getAbsolutePath()) / 100 ; seekBar.setMax(time); Toast.makeText( this , "长度:" + time, Toast.LENGTH_LONG).show(); // 开始线程,更新进度条的刻度 new Thread() { @Override public void run() { try { isPlaying = true ; while (isPlaying) { // 如果正在播放,0.1.毫秒更新一次进度条 final int current = vv_video.getCurrentPosition() / 100 ; seekBar.setProgress(current); /* try { myText = "总时间:" + time / 10 + "秒,目前:" + current / 10 + "秒"; // pTextView.setText("总时间:" + time / 10 + "秒,目前:" + current / 10 + "秒"); new WorkThread().start(); } catch (Exception ex) { Log.d("错误:", ex.getMessage().toString()); }*/ new Thread() { public void run() { myText = "总时间:" + time / 10 + "秒,目前:" + current / 10 + "秒" ; handler.post(updateUIRunnable); } }.start(); //Toast.makeText(this, "当前:"+current,Toast.LENGTH_LONG).show(); sleep( 100 ); } } catch (Exception e) { e.printStackTrace(); } } }.start(); // 播放之后设置播放按钮不可用 btn_play.setEnabled( false ); vv_video.setOnCompletionListener( new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // 在播放完毕被回调 btn_play.setEnabled( true ); } }); vv_video.setOnErrorListener( new OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { // 发生错误重新播放 play( 0 ); isPlaying = false ; return false ; } }); } //工作线程 private class WorkThread extends Thread { @Override public void run() { try { pTextView.setText(myText); } catch (Exception ex) { Log.e( "严重错误:" , ex.getMessage().toString()); } } } // 构建Runnable对象,并在runnable中更新UI Runnable updateUIRunnable = new Runnable() { @Override public void run() { try { pTextView.setText(myText); } catch (Exception ex) { Log.e( "严重错误:" , ex.getMessage().toString()); } } }; |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
2012-10-06 C#窗体关闭事件的重载实例(转)
2009-10-06 mapinfo 的WOR文件转换成mapx的GST文件
2009-10-06 C#进行MapX二次开发之图层操作