android 多线程 切换视频图片使用心得
2014-08-19 16:41
507 查看
package com.tk.box.activity;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.MediaController;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.widget.VideoView;
import com.tk.box.bo.task.AreaModel;
import com.tk.box.bo.task.MediaModel;
import com.tk.box.bo.task.TaskModel;
import com.tk.box.service.TaskService;
import com.tk.box.service.impl.TaskServiceImpl;
/**
* 总结下 多线程的使用心得; 1 像是这种 多个布局 同时播放; 但是不同步 更新(每个布局里面的内容不一样) 肯定是 每个布局使用一个多线程进行管理;
* 因为每个布局的播放时间不一样;不同步; 所以每个 线程里面肯定都各自有 是否改变界面的变量 以及 各自对应的 mediaList; 还有 对应的布局 ;
* 所以构造器如下;
*
* public MyThread(Integer layoutId, List<MediaModel> mediaList, String
* palyIngType, String threadId) {
*
* 每个布局对应一个线程; 把每个布局里面的media素材 装到 list 里面; 取出来第一个进行显示; 每个布局对应一个线程 ; 开始计时 ;
* 在线程里面; 先 简单的sleep 一下;(原来的时候我根据不同的素材类型进行不同的sleep; 比如 在播放 素材是视频的时候; 我用变量
* videoIsEnd 以及palyIngType 进行控制; 后来发现 不理想; 我在主线程 根据子线程的id 改变 某个子线程的 palyIngType
* 变量的时候 发现 效果不理想;界面没有及时更新; 仔细分析了下; 很可能是 在 执行sleep代码的时候(因为sleep
* 时间比较长;远远超过了代码执行的时间)) 比如原来的palyIngType 是image; 判断完毕进入到if
* (!"video".equals(palyIngType)) { Thread.sleep(sleepTime);} 里面的时候;此时正在sleep;
* 我在主线程里面改变了次线程的palyIngType 为video; 这个时候我本来想 让 界面不进行切换; 继续 播放 视频文件;
* 也就是希望执行while ("video".equals(palyIngType) && !videoIsEnd) {//
* 没有播放完成;Thread.sleep(sleepTime);} 这段代码; 实际上 却没有执行; 导致切换不理想;
*
* 解决方案: 就是在线程里面简单的sleep; 不进行逻辑的判断; 如下; 控制是否切换的逻辑在核心的 控制是否发生消息 来解决 ; 而不是在 控制睡多久来
* 控制业务逻辑; 大不了跑一圈什么也不做;
*
*
*
*
* 原来不好的代码如下; long sleepTime=10000; if (!"video".equals(palyIngType)) {// 图片
* Thread.sleep(sleepTime);
*
* } else { // 原来播放的是视频;如果是视频的话 一直等待; 上一个 播放的是视频; 并且没有播放完; 就一直等待;
*
* while ("video".equals(palyIngType) && !videoIsEnd) {// 没有播放完成;
*
* Thread.sleep(sleepTime);
*
* }
*
*
*
*
*
*/
public class InquiryMainActivity extends Activity {
private TaskService taskService = null;
private boolean videoIsEnd = false;
private String TAG = "InquiryMainActivity";
private LinearLayout videoviewlayout = null;
private Uri mUri = null;
private VideoView vv = null;
private List<MyThread> threadList = new ArrayList<InquiryMainActivity.MyThread>();
// video view begin ;
private Handler handler = new UIHander();
private final class UIHander extends Handler {
private ImageView imageView = null;
private RelativeLayout layout = null;
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
case 2:
case 3:
String path = msg.getData().getString("path");
String threadId = msg.getData().getString("threadId");
Integer currentIndex = msg.getData().getInt("currentIndex");
Integer layoutId = msg.getData().getInt("layoutId");
layout = (RelativeLayout) InquiryMainActivity.this
.findViewById(layoutId);
layout.removeAllViews();
if (path.endsWith(".mp4")) {// 下个播放的 是mp4
initVideoView();
layout.addView(videoviewlayout,
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
for (MyThread perThread : threadList) {
//
// Log.i(TAG, threadId + "threadId便利每个 线程的id-----"
// + perThread.getThreadId());
if (threadId.equals(perThread.getThreadId())) {
Log.i(TAG, threadId
+ "的获取到threadId----- 进行 设置playType"
+ perThread.getThreadId());
perThread.setPalyIngType("video");
videoIsEnd = false;// 没有结束; 否则不等待;
}
// perThread.getth threadId
}
// perAreaLayout.addView(videoviewlayout, 0,
// new RelativeLayout.LayoutParams(
// RelativeLayout.LayoutParams.FILL_PARENT,
// RelativeLayout.LayoutParams.FILL_PARENT));
// palyIngType = "video";
showMp4();
} else if (path.endsWith(".jpg")) {
imageView = new ImageView(InquiryMainActivity.this);
Bitmap bitmap = getLoacalBitmap(Environment
.getExternalStorageDirectory() + "/" + path); // 从本地取图片(在cdcard中获取)
imageView.setScaleType(ScaleType.FIT_XY);// 充满;
imageView = new ImageView(InquiryMainActivity.this);
imageView.setImageBitmap(bitmap);
layout.addView(imageView, new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
for (MyThread perThread : threadList) {
if (threadId.equals(perThread.getThreadId())) {
// Log.i(TAG, threadId
// + "的获取到threadId----- 进行 设置playType"
// + perThread.getThreadId());
perThread.setPalyIngType("image");
// videoIsEnd = true;//
}
// perThread.getth threadId
}
} else if (path.endsWith("")) {
}
break;
}
}
}
private void initVideoView() {
// mIntent = getIntent();
// if (mIntent != null) {
// 把播放地址取出来
// mUri =mIntent.getData();
// file:///mnt/sdcard/pptv/download/%E5%AE%AB%E9%94%81%E7%8F%A0%E5%B8%98(%E7%AC%AC06%E9%9B%86).mp4
// mUri
// =Uri.parse("file:///mnt/sdcard/pptv/download/%E5%AE%AB%E9%94%81%E7%8F%A0%E5%B8%98(%E7%AC%AC06%E9%9B%86).mp4");
// mUri = Uri.parse("file:///data/data/02.avi");
// mUri = Uri.parse("file:///data/data/01.mp4");
mUri = Uri.parse("file:///mnt/sdcard/video/01.mp4");
if (mUri != null) {
// 传播放地址给播放器
vv.setVideoURI(mUri);
}
// }
// 当准备好了,会有回调
vv.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
// 1,定位到上次播放的地方(seekTo());2,取消等待画面
// 当准备好了,开始播放
if (vv != null)
vv.start();
}
});
// 当播放出错了,也会有一个回调
vv.setOnErrorListener(new OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// 进行错误处理:1,提示用户;2,重试,3,进入第三方播放器继续播放;
Toast.makeText(InquiryMainActivity.this, "播放出错了", 1).show();
return true;
}
});
// 监听播放完成
vv.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// 播放完成:1,退出播放器、提示用户是否进入你的软件;2,播放下一个视频
Toast.makeText(InquiryMainActivity.this, "播放完了", 1).show();
videoIsEnd = true;
}
});
// 显示系统空间
MediaController me = new MediaController(InquiryMainActivity.this);
me.setPadding(200, 0, 0, 0);
vv.setMediaController(me);
}
private void showMp4() {
initVideoView();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
videoviewlayout = (LinearLayout) getLayoutInflater().inflate(
R.layout.videoview, null); // 通过这种方式初始化布局文件;
vv = (VideoView) videoviewlayout.findViewById(R.id.vv);
taskService = new TaskServiceImpl(this);
// 访问sd 卡 ;需要加上 路径;
String path = Environment.getExternalStorageDirectory() + "/task.xml";
TaskModel task = taskService.readTaskFromTaskXMl(path);
if (task == null) {
Toast.makeText(this, "读取xml文件失败", 1).show();
} else {
String taskname = task.getName();
String startDate = task.getStartDate();
String endDate = task.getEndDate();
Integer weeks = task.getWeek();
}
Display mDisplay = getWindowManager().getDefaultDisplay();
int w = mDisplay.getWidth();
int h = mDisplay.getHeight();
// 1920 1080 1280 752 ;
double widthScalPercent = 1920.0 / w;
double heightScalePercent = 1080.0 / h;
RelativeLayout global = (RelativeLayout) getLayoutInflater().inflate(
R.layout.inquiry_main, null);
// TextView mTextView = new TextView(this);
//
// mTextView.setText("测试--------------------------");
ImageView view = new ImageView(this);
view.setBackgroundColor(Color.RED);
// android.widget.RelativeLayout.LayoutParams lineimageViewlayoutParams
// = new RelativeLayout.LayoutParams(
// 100, 100);// 也就是设置imgaeview 的宽高; 也就是设置要添加的控件的宽高;
// lineimageViewlayoutParams.topMargin = 100.0;// 设置上边距;
// global.addView(view, lineimageViewlayoutParams);
// global.addView(view, 200, 200);// 也可以通过这种设置宽高; 放前面或者后面都可以;
setContentView(global);
// global.addView(view, lineimageViewlayoutParams);
List<AreaModel> areaList = task.getProgram().getAreaList();
Integer index = 0;
List<Integer> areIndex = new ArrayList<Integer>();
areIndex.add(Color.RED);
areIndex.add(Color.BLUE);
areIndex.add(Color.GRAY);
areIndex.add(Color.YELLOW);
List<Map<Integer, List<MediaModel>>> mapModelList = new ArrayList<Map<Integer, List<MediaModel>>>();
boolean isFirst = true;
for (AreaModel area : areaList) {
Map<Integer, List<MediaModel>> map = new HashMap<Integer, List<MediaModel>>();
List<MediaModel> mediaList = area.getMediaModelList();
Double height = area.getHeight();
Double width = area.getWidth();
Double startX = area.getStartX();
Double startY = area.getStartY();
Integer newHeight = (int) (height / heightScalePercent);
Integer newWidth = (int) (width / widthScalPercent);
Integer newstartX = (int) (startX / widthScalPercent);
Integer newstartY = (int) (startY / heightScalePercent);
RelativeLayout perAreaLayout = new RelativeLayout(this);
perAreaLayout.setBackgroundColor(areIndex.get(index));
Integer layoutId = 1000 + index;
perAreaLayout.setId(layoutId);
map.put(layoutId, mediaList);
mapModelList.add(map);
android.widget.RelativeLayout.LayoutParams arealayoutParams = new RelativeLayout.LayoutParams(
newWidth, newHeight);
arealayoutParams.topMargin = newstartY;// 设置上边距;
arealayoutParams.leftMargin = newstartX;
String palyIngType = "";// image 图片 2 video; 正在播放的类型;
if (mediaList != null && mediaList.size() > 0
&& mediaList.get(0).getName().endsWith(".jpg")) {
// 设置默认的显示;
ImageView imageView = new ImageView(this);
// step1 让 图片充满控件; 不仅仅要设置模式为scaleType
imageView.setScaleType(ScaleType.FIT_XY);//
imageView.setBackgroundResource(R.drawable.icon);
// 有些事情必须在 addView 之前做; 否则不显示;
// step2让 图片充满控件; // 还需要设置图片宽高都是填充父元素; 如下
perAreaLayout.addView(imageView, 0,
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
palyIngType = "image";
} else if (mediaList != null && mediaList.size() > 0
&& mediaList.get(0).getName().endsWith(".mp4")) {
perAreaLayout.addView(videoviewlayout, 0,
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
// isPlayingVideo = true;
showMp4();
palyIngType = "video";
videoIsEnd = false;
}
global.addView(perAreaLayout, arealayoutParams);
// Thread.sleep(time)
MyThread thread = new MyThread(layoutId, mediaList, palyIngType,
(UUID.randomUUID().toString()));
threadList.add(thread);
thread.start();
index++;
}
}
private boolean flag = true;
private class MyThread extends Thread {
private String threadId = null;
private Integer layoutId = null;
private String palyIngType = "";// 上一个是否是播放的类型;
public String getThreadId() {
return threadId;
}
public void setPalyIngType(String palyIngType) {
this.palyIngType = palyIngType;
}
List<MediaModel> mediaList = null;
private Integer currentIndex = null;
private RelativeLayout layout = null;
private String threadName = "";
public MyThread(Integer layoutId, List<MediaModel> mediaList,
String palyIngType, String threadId) {
this.layoutId = layoutId;
threadName = "ThreadName-" + layoutId;
this.threadId = threadId;
this.mediaList = mediaList;
layout = (RelativeLayout) InquiryMainActivity.this
.findViewById(layoutId);
this.palyIngType = palyIngType;
if (mediaList != null && mediaList.size() > 0) {
currentIndex = 0;
}
// Log.i(TAG, "创建的是" + threadName + " palyIngType:" + palyIngType);
}
@Override
public void run() {
// super.run();
// 访问sd 卡 ;需要加上 路径;
try {
while (flag) {
try {
long sleepTime = 10000;
// 有可能判断完成了; 原来是已经判断完是image; 在这里睡呢;沉睡的时候改变成为video;
// 导致不能等待;
Thread.sleep(sleepTime);
/**
* 自己感觉尽量不要在 if 语句里面判断是否进行 sleep ; 因为有可能 判断 完成之后 在sleep的
* 时候 进行状态的改变; 导致 判断出现不准确的情况; 我是在最后发生给主线程的消息的时候进行状态的判断;
* 如果播放完毕; 就 发送消息 ; 如果没有播放完成的话; 就 继续播放; 继续while 循环 ;
*
*
*/
// if (!"video".equals(palyIngType)) {// 图片的话一秒跳一次;
// if (threadName.indexOf("002") >= 0)
// Log.i(TAG, threadName
// + "切换图片三秒------palyIngType:"
// + palyIngType + "threadId:" + threadId);
// Thread.sleep(sleepTime);
//
// } else { // 原来播放的是视频;
// // 如果是视频的话 一直等待; 上一个 播放的是视频; 并且没有播放完; 就一直等待;
// if (threadName.indexOf("002") >= 0)
// Log.i(TAG, threadName + "----palyIngType:-----"
// + palyIngType + "threadId:" + threadId);
// while ("video".equals(palyIngType) && !videoIsEnd)
// {// 没有播放完成;
// if (threadName.indexOf("002") >= 0)
// Log.i(TAG, threadName
// + "播放的是视频---等待三秒------palyIngType:"
// + palyIngType + "threadId:"
// + threadId);
// Thread.sleep(sleepTime);
//
// }
//
// }
} catch (Exception e) {
e.printStackTrace();
}
currentIndex += 1;
if (currentIndex >= mediaList.size()) {
currentIndex = 0;
}
// 下一个要播放的媒体;
MediaModel toBePlayedMedia = mediaList.get(currentIndex);
String path = toBePlayedMedia.getName();
if (threadName.indexOf("002") >= 0)
Log.i(TAG, " 发送消息前 ---------------------path:" + path
+ "playType:" + palyIngType + "videoIsEnd"
+ videoIsEnd);
// if (path.endsWith(".jpg") &&
// !"video".equals(palyIngType)) {// 如果上次播放的不是
// 视频;
// 并且下次播放的也是图片
if (path.endsWith(".jpg") && "image".equals(palyIngType)) {// 如果上次播放的不是
Message msg = new Message();
msg.what = 1;
msg.getData().putString("path", path);
msg.getData().putInt("currentIndex", currentIndex);
msg.getData().putInt("layoutId", layoutId);
msg.getData().putString("threadId", threadId);
handler.sendMessage(msg);
if (threadName.indexOf("002") >= 0)
Log.i(TAG,
" 发送消息---------------------------------1-----palyIngTypeold:"
+ palyIngType + "被改为image;");
// palyIngType = "image";// 正在播放的是图片; 在handler 进行控制就好了;
} else if ("video".equals(palyIngType)
&& path.endsWith(".jpg")) {
// 如果上次播放的是 视频; 并且下次播放的也是图片
if (threadName.indexOf("002") >= 0)
Log.i(TAG,
" 发送消息---------------------------------2-----palyIngTypeold:---"
+ palyIngType + "依旧;");
// if (videoIsEnd) {// 因为 前面的话 有可能判断成为 image 之后
// Log.i(TAG, threadName + "视频--------->图片 发送消息;");
if (videoIsEnd) { // 控制是否切换界面
Message msg = new Message();
msg.what = 2;
msg.getData().putString("path", path);
msg.getData().putString("palyIngType", palyIngType);// 把之前的播放类型发过去;
msg.getData().putInt("currentIndex", currentIndex);
msg.getData().putInt("layoutId", layoutId);
msg.getData().putString("threadId", threadId);
handler.sendMessage(msg);
}
// }
// isPlayingVideo = false;// 发送消息并且这次播放的不是视频;
// palyIngType = "image";//
} else if ("image".equals(palyIngType)
&& path.endsWith(".mp4")) {// 图片转视频ok;
if (threadName.indexOf("002") >= 0)
Log.i(TAG,
" 发送消息---------------------------------3-----palyIngTypeold:"
+ palyIngType + "依旧;");
// if (!videoIsEnd) {//
// 正在播放的是 图片; 下次播放视频;
Message msg = new Message();
msg.what = 3;
msg.getData().putString("path", path);
msg.getData().putString("palyIngType", palyIngType);// 把之前的播放类型发过去;
msg.getData().putInt("currentIndex", currentIndex);
msg.getData().putInt("layoutId", layoutId);
msg.getData().putString("threadId", threadId);
handler.sendMessage(msg);
// }
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* // 测试; 具体还没有细化; 还没有细化 控制线程变量 什么的 ;
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) { // 监控/拦截/屏蔽返回键
// do something
// 返回键; 执行了;可以再这里进行监听;
Log.i(TAG, "back------被执行了; 线程要关闭了 ----");
flag = false;
// 如果返回false 那么阻止事件继续执行;
// return false;
} else if (keyCode == KeyEvent.KEYCODE_MENU) {
// 点击未执行;
Log.i(TAG, "MENU------被执行了; 线程要关闭了 ----");
flag = false;
// do something
} else if (keyCode == KeyEvent.KEYCODE_HOME) {
// 点击未执行;
Log.i(TAG, "KEYCODE_HOME------被执行了; 线程要关闭了 ----");
// 这里操作是没有返回结果的
}
return super.onKeyDown(keyCode, event);
}
/**
* 加载本地图片
*
* @param url
* @return
*/
public static Bitmap getLoacalBitmap(String url) {
try {
FileInputStream fis = new FileInputStream(url);
return BitmapFactory.decodeStream(fis); // /把流转化为Bitmap图片
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.MediaController;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.widget.VideoView;
import com.tk.box.bo.task.AreaModel;
import com.tk.box.bo.task.MediaModel;
import com.tk.box.bo.task.TaskModel;
import com.tk.box.service.TaskService;
import com.tk.box.service.impl.TaskServiceImpl;
/**
* 总结下 多线程的使用心得; 1 像是这种 多个布局 同时播放; 但是不同步 更新(每个布局里面的内容不一样) 肯定是 每个布局使用一个多线程进行管理;
* 因为每个布局的播放时间不一样;不同步; 所以每个 线程里面肯定都各自有 是否改变界面的变量 以及 各自对应的 mediaList; 还有 对应的布局 ;
* 所以构造器如下;
*
* public MyThread(Integer layoutId, List<MediaModel> mediaList, String
* palyIngType, String threadId) {
*
* 每个布局对应一个线程; 把每个布局里面的media素材 装到 list 里面; 取出来第一个进行显示; 每个布局对应一个线程 ; 开始计时 ;
* 在线程里面; 先 简单的sleep 一下;(原来的时候我根据不同的素材类型进行不同的sleep; 比如 在播放 素材是视频的时候; 我用变量
* videoIsEnd 以及palyIngType 进行控制; 后来发现 不理想; 我在主线程 根据子线程的id 改变 某个子线程的 palyIngType
* 变量的时候 发现 效果不理想;界面没有及时更新; 仔细分析了下; 很可能是 在 执行sleep代码的时候(因为sleep
* 时间比较长;远远超过了代码执行的时间)) 比如原来的palyIngType 是image; 判断完毕进入到if
* (!"video".equals(palyIngType)) { Thread.sleep(sleepTime);} 里面的时候;此时正在sleep;
* 我在主线程里面改变了次线程的palyIngType 为video; 这个时候我本来想 让 界面不进行切换; 继续 播放 视频文件;
* 也就是希望执行while ("video".equals(palyIngType) && !videoIsEnd) {//
* 没有播放完成;Thread.sleep(sleepTime);} 这段代码; 实际上 却没有执行; 导致切换不理想;
*
* 解决方案: 就是在线程里面简单的sleep; 不进行逻辑的判断; 如下; 控制是否切换的逻辑在核心的 控制是否发生消息 来解决 ; 而不是在 控制睡多久来
* 控制业务逻辑; 大不了跑一圈什么也不做;
*
*
*
*
* 原来不好的代码如下; long sleepTime=10000; if (!"video".equals(palyIngType)) {// 图片
* Thread.sleep(sleepTime);
*
* } else { // 原来播放的是视频;如果是视频的话 一直等待; 上一个 播放的是视频; 并且没有播放完; 就一直等待;
*
* while ("video".equals(palyIngType) && !videoIsEnd) {// 没有播放完成;
*
* Thread.sleep(sleepTime);
*
* }
*
*
*
*
*
*/
public class InquiryMainActivity extends Activity {
private TaskService taskService = null;
private boolean videoIsEnd = false;
private String TAG = "InquiryMainActivity";
private LinearLayout videoviewlayout = null;
private Uri mUri = null;
private VideoView vv = null;
private List<MyThread> threadList = new ArrayList<InquiryMainActivity.MyThread>();
// video view begin ;
private Handler handler = new UIHander();
private final class UIHander extends Handler {
private ImageView imageView = null;
private RelativeLayout layout = null;
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
case 2:
case 3:
String path = msg.getData().getString("path");
String threadId = msg.getData().getString("threadId");
Integer currentIndex = msg.getData().getInt("currentIndex");
Integer layoutId = msg.getData().getInt("layoutId");
layout = (RelativeLayout) InquiryMainActivity.this
.findViewById(layoutId);
layout.removeAllViews();
if (path.endsWith(".mp4")) {// 下个播放的 是mp4
initVideoView();
layout.addView(videoviewlayout,
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
for (MyThread perThread : threadList) {
//
// Log.i(TAG, threadId + "threadId便利每个 线程的id-----"
// + perThread.getThreadId());
if (threadId.equals(perThread.getThreadId())) {
Log.i(TAG, threadId
+ "的获取到threadId----- 进行 设置playType"
+ perThread.getThreadId());
perThread.setPalyIngType("video");
videoIsEnd = false;// 没有结束; 否则不等待;
}
// perThread.getth threadId
}
// perAreaLayout.addView(videoviewlayout, 0,
// new RelativeLayout.LayoutParams(
// RelativeLayout.LayoutParams.FILL_PARENT,
// RelativeLayout.LayoutParams.FILL_PARENT));
// palyIngType = "video";
showMp4();
} else if (path.endsWith(".jpg")) {
imageView = new ImageView(InquiryMainActivity.this);
Bitmap bitmap = getLoacalBitmap(Environment
.getExternalStorageDirectory() + "/" + path); // 从本地取图片(在cdcard中获取)
imageView.setScaleType(ScaleType.FIT_XY);// 充满;
imageView = new ImageView(InquiryMainActivity.this);
imageView.setImageBitmap(bitmap);
layout.addView(imageView, new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
for (MyThread perThread : threadList) {
if (threadId.equals(perThread.getThreadId())) {
// Log.i(TAG, threadId
// + "的获取到threadId----- 进行 设置playType"
// + perThread.getThreadId());
perThread.setPalyIngType("image");
// videoIsEnd = true;//
}
// perThread.getth threadId
}
} else if (path.endsWith("")) {
}
break;
}
}
}
private void initVideoView() {
// mIntent = getIntent();
// if (mIntent != null) {
// 把播放地址取出来
// mUri =mIntent.getData();
// file:///mnt/sdcard/pptv/download/%E5%AE%AB%E9%94%81%E7%8F%A0%E5%B8%98(%E7%AC%AC06%E9%9B%86).mp4
// mUri
// =Uri.parse("file:///mnt/sdcard/pptv/download/%E5%AE%AB%E9%94%81%E7%8F%A0%E5%B8%98(%E7%AC%AC06%E9%9B%86).mp4");
// mUri = Uri.parse("file:///data/data/02.avi");
// mUri = Uri.parse("file:///data/data/01.mp4");
mUri = Uri.parse("file:///mnt/sdcard/video/01.mp4");
if (mUri != null) {
// 传播放地址给播放器
vv.setVideoURI(mUri);
}
// }
// 当准备好了,会有回调
vv.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
// 1,定位到上次播放的地方(seekTo());2,取消等待画面
// 当准备好了,开始播放
if (vv != null)
vv.start();
}
});
// 当播放出错了,也会有一个回调
vv.setOnErrorListener(new OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// 进行错误处理:1,提示用户;2,重试,3,进入第三方播放器继续播放;
Toast.makeText(InquiryMainActivity.this, "播放出错了", 1).show();
return true;
}
});
// 监听播放完成
vv.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// 播放完成:1,退出播放器、提示用户是否进入你的软件;2,播放下一个视频
Toast.makeText(InquiryMainActivity.this, "播放完了", 1).show();
videoIsEnd = true;
}
});
// 显示系统空间
MediaController me = new MediaController(InquiryMainActivity.this);
me.setPadding(200, 0, 0, 0);
vv.setMediaController(me);
}
private void showMp4() {
initVideoView();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
videoviewlayout = (LinearLayout) getLayoutInflater().inflate(
R.layout.videoview, null); // 通过这种方式初始化布局文件;
vv = (VideoView) videoviewlayout.findViewById(R.id.vv);
taskService = new TaskServiceImpl(this);
// 访问sd 卡 ;需要加上 路径;
String path = Environment.getExternalStorageDirectory() + "/task.xml";
TaskModel task = taskService.readTaskFromTaskXMl(path);
if (task == null) {
Toast.makeText(this, "读取xml文件失败", 1).show();
} else {
String taskname = task.getName();
String startDate = task.getStartDate();
String endDate = task.getEndDate();
Integer weeks = task.getWeek();
}
Display mDisplay = getWindowManager().getDefaultDisplay();
int w = mDisplay.getWidth();
int h = mDisplay.getHeight();
// 1920 1080 1280 752 ;
double widthScalPercent = 1920.0 / w;
double heightScalePercent = 1080.0 / h;
RelativeLayout global = (RelativeLayout) getLayoutInflater().inflate(
R.layout.inquiry_main, null);
// TextView mTextView = new TextView(this);
//
// mTextView.setText("测试--------------------------");
ImageView view = new ImageView(this);
view.setBackgroundColor(Color.RED);
// android.widget.RelativeLayout.LayoutParams lineimageViewlayoutParams
// = new RelativeLayout.LayoutParams(
// 100, 100);// 也就是设置imgaeview 的宽高; 也就是设置要添加的控件的宽高;
// lineimageViewlayoutParams.topMargin = 100.0;// 设置上边距;
// global.addView(view, lineimageViewlayoutParams);
// global.addView(view, 200, 200);// 也可以通过这种设置宽高; 放前面或者后面都可以;
setContentView(global);
// global.addView(view, lineimageViewlayoutParams);
List<AreaModel> areaList = task.getProgram().getAreaList();
Integer index = 0;
List<Integer> areIndex = new ArrayList<Integer>();
areIndex.add(Color.RED);
areIndex.add(Color.BLUE);
areIndex.add(Color.GRAY);
areIndex.add(Color.YELLOW);
List<Map<Integer, List<MediaModel>>> mapModelList = new ArrayList<Map<Integer, List<MediaModel>>>();
boolean isFirst = true;
for (AreaModel area : areaList) {
Map<Integer, List<MediaModel>> map = new HashMap<Integer, List<MediaModel>>();
List<MediaModel> mediaList = area.getMediaModelList();
Double height = area.getHeight();
Double width = area.getWidth();
Double startX = area.getStartX();
Double startY = area.getStartY();
Integer newHeight = (int) (height / heightScalePercent);
Integer newWidth = (int) (width / widthScalPercent);
Integer newstartX = (int) (startX / widthScalPercent);
Integer newstartY = (int) (startY / heightScalePercent);
RelativeLayout perAreaLayout = new RelativeLayout(this);
perAreaLayout.setBackgroundColor(areIndex.get(index));
Integer layoutId = 1000 + index;
perAreaLayout.setId(layoutId);
map.put(layoutId, mediaList);
mapModelList.add(map);
android.widget.RelativeLayout.LayoutParams arealayoutParams = new RelativeLayout.LayoutParams(
newWidth, newHeight);
arealayoutParams.topMargin = newstartY;// 设置上边距;
arealayoutParams.leftMargin = newstartX;
String palyIngType = "";// image 图片 2 video; 正在播放的类型;
if (mediaList != null && mediaList.size() > 0
&& mediaList.get(0).getName().endsWith(".jpg")) {
// 设置默认的显示;
ImageView imageView = new ImageView(this);
// step1 让 图片充满控件; 不仅仅要设置模式为scaleType
imageView.setScaleType(ScaleType.FIT_XY);//
imageView.setBackgroundResource(R.drawable.icon);
// 有些事情必须在 addView 之前做; 否则不显示;
// step2让 图片充满控件; // 还需要设置图片宽高都是填充父元素; 如下
perAreaLayout.addView(imageView, 0,
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
palyIngType = "image";
} else if (mediaList != null && mediaList.size() > 0
&& mediaList.get(0).getName().endsWith(".mp4")) {
perAreaLayout.addView(videoviewlayout, 0,
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
// isPlayingVideo = true;
showMp4();
palyIngType = "video";
videoIsEnd = false;
}
global.addView(perAreaLayout, arealayoutParams);
// Thread.sleep(time)
MyThread thread = new MyThread(layoutId, mediaList, palyIngType,
(UUID.randomUUID().toString()));
threadList.add(thread);
thread.start();
index++;
}
}
private boolean flag = true;
private class MyThread extends Thread {
private String threadId = null;
private Integer layoutId = null;
private String palyIngType = "";// 上一个是否是播放的类型;
public String getThreadId() {
return threadId;
}
public void setPalyIngType(String palyIngType) {
this.palyIngType = palyIngType;
}
List<MediaModel> mediaList = null;
private Integer currentIndex = null;
private RelativeLayout layout = null;
private String threadName = "";
public MyThread(Integer layoutId, List<MediaModel> mediaList,
String palyIngType, String threadId) {
this.layoutId = layoutId;
threadName = "ThreadName-" + layoutId;
this.threadId = threadId;
this.mediaList = mediaList;
layout = (RelativeLayout) InquiryMainActivity.this
.findViewById(layoutId);
this.palyIngType = palyIngType;
if (mediaList != null && mediaList.size() > 0) {
currentIndex = 0;
}
// Log.i(TAG, "创建的是" + threadName + " palyIngType:" + palyIngType);
}
@Override
public void run() {
// super.run();
// 访问sd 卡 ;需要加上 路径;
try {
while (flag) {
try {
long sleepTime = 10000;
// 有可能判断完成了; 原来是已经判断完是image; 在这里睡呢;沉睡的时候改变成为video;
// 导致不能等待;
Thread.sleep(sleepTime);
/**
* 自己感觉尽量不要在 if 语句里面判断是否进行 sleep ; 因为有可能 判断 完成之后 在sleep的
* 时候 进行状态的改变; 导致 判断出现不准确的情况; 我是在最后发生给主线程的消息的时候进行状态的判断;
* 如果播放完毕; 就 发送消息 ; 如果没有播放完成的话; 就 继续播放; 继续while 循环 ;
*
*
*/
// if (!"video".equals(palyIngType)) {// 图片的话一秒跳一次;
// if (threadName.indexOf("002") >= 0)
// Log.i(TAG, threadName
// + "切换图片三秒------palyIngType:"
// + palyIngType + "threadId:" + threadId);
// Thread.sleep(sleepTime);
//
// } else { // 原来播放的是视频;
// // 如果是视频的话 一直等待; 上一个 播放的是视频; 并且没有播放完; 就一直等待;
// if (threadName.indexOf("002") >= 0)
// Log.i(TAG, threadName + "----palyIngType:-----"
// + palyIngType + "threadId:" + threadId);
// while ("video".equals(palyIngType) && !videoIsEnd)
// {// 没有播放完成;
// if (threadName.indexOf("002") >= 0)
// Log.i(TAG, threadName
// + "播放的是视频---等待三秒------palyIngType:"
// + palyIngType + "threadId:"
// + threadId);
// Thread.sleep(sleepTime);
//
// }
//
// }
} catch (Exception e) {
e.printStackTrace();
}
currentIndex += 1;
if (currentIndex >= mediaList.size()) {
currentIndex = 0;
}
// 下一个要播放的媒体;
MediaModel toBePlayedMedia = mediaList.get(currentIndex);
String path = toBePlayedMedia.getName();
if (threadName.indexOf("002") >= 0)
Log.i(TAG, " 发送消息前 ---------------------path:" + path
+ "playType:" + palyIngType + "videoIsEnd"
+ videoIsEnd);
// if (path.endsWith(".jpg") &&
// !"video".equals(palyIngType)) {// 如果上次播放的不是
// 视频;
// 并且下次播放的也是图片
if (path.endsWith(".jpg") && "image".equals(palyIngType)) {// 如果上次播放的不是
Message msg = new Message();
msg.what = 1;
msg.getData().putString("path", path);
msg.getData().putInt("currentIndex", currentIndex);
msg.getData().putInt("layoutId", layoutId);
msg.getData().putString("threadId", threadId);
handler.sendMessage(msg);
if (threadName.indexOf("002") >= 0)
Log.i(TAG,
" 发送消息---------------------------------1-----palyIngTypeold:"
+ palyIngType + "被改为image;");
// palyIngType = "image";// 正在播放的是图片; 在handler 进行控制就好了;
} else if ("video".equals(palyIngType)
&& path.endsWith(".jpg")) {
// 如果上次播放的是 视频; 并且下次播放的也是图片
if (threadName.indexOf("002") >= 0)
Log.i(TAG,
" 发送消息---------------------------------2-----palyIngTypeold:---"
+ palyIngType + "依旧;");
// if (videoIsEnd) {// 因为 前面的话 有可能判断成为 image 之后
// Log.i(TAG, threadName + "视频--------->图片 发送消息;");
if (videoIsEnd) { // 控制是否切换界面
Message msg = new Message();
msg.what = 2;
msg.getData().putString("path", path);
msg.getData().putString("palyIngType", palyIngType);// 把之前的播放类型发过去;
msg.getData().putInt("currentIndex", currentIndex);
msg.getData().putInt("layoutId", layoutId);
msg.getData().putString("threadId", threadId);
handler.sendMessage(msg);
}
// }
// isPlayingVideo = false;// 发送消息并且这次播放的不是视频;
// palyIngType = "image";//
} else if ("image".equals(palyIngType)
&& path.endsWith(".mp4")) {// 图片转视频ok;
if (threadName.indexOf("002") >= 0)
Log.i(TAG,
" 发送消息---------------------------------3-----palyIngTypeold:"
+ palyIngType + "依旧;");
// if (!videoIsEnd) {//
// 正在播放的是 图片; 下次播放视频;
Message msg = new Message();
msg.what = 3;
msg.getData().putString("path", path);
msg.getData().putString("palyIngType", palyIngType);// 把之前的播放类型发过去;
msg.getData().putInt("currentIndex", currentIndex);
msg.getData().putInt("layoutId", layoutId);
msg.getData().putString("threadId", threadId);
handler.sendMessage(msg);
// }
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* // 测试; 具体还没有细化; 还没有细化 控制线程变量 什么的 ;
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) { // 监控/拦截/屏蔽返回键
// do something
// 返回键; 执行了;可以再这里进行监听;
Log.i(TAG, "back------被执行了; 线程要关闭了 ----");
flag = false;
// 如果返回false 那么阻止事件继续执行;
// return false;
} else if (keyCode == KeyEvent.KEYCODE_MENU) {
// 点击未执行;
Log.i(TAG, "MENU------被执行了; 线程要关闭了 ----");
flag = false;
// do something
} else if (keyCode == KeyEvent.KEYCODE_HOME) {
// 点击未执行;
Log.i(TAG, "KEYCODE_HOME------被执行了; 线程要关闭了 ----");
// 这里操作是没有返回结果的
}
return super.onKeyDown(keyCode, event);
}
/**
* 加载本地图片
*
* @param url
* @return
*/
public static Bitmap getLoacalBitmap(String url) {
try {
FileInputStream fis = new FileInputStream(url);
return BitmapFactory.decodeStream(fis); // /把流转化为Bitmap图片
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
}
相关文章推荐
- RxJava-RxAndroid 使用心得-看视频收藏的图片
- Android 多线程:使用Thread和Handler (从网络上获取图片)
- Android编程心得-使用ActionBar+Fragment+ViewPager实现动态切换Menu效果
- Android中使用ViewPager实现图片的切换
- Android中使用ImageViewSwitcher实现图片切换轮播导航效果
- Android开发之使用ViewPager实现图片左右滑动切换效果
- Android中使用又拍云存储来上传文件(包括图片、音频和视频等)
- android 使用ThumbnailUtils类获取图片、视频的缩略图
- Android:使用ViewPager实现左右滑动切换图片 (简单版)
- android上传图片、视频、文件,服务端使用wcf接收
- 视频框架 Vitamio 使用教程+部分心得 (六) 适配 Android 7.0 MediaController显示
- Android:使用ViewPager实现左右滑动切换图片 (简单版)
- Android:使用ViewPager实现左右滑动切换图片(图上有点点)
- Android开发之ImageSwitcher组件的使用以及设置图片切换的效果
- Retrofit 使用心得-看视频收藏的图片
- Android中使用RadioButton实现QQ底部图片切换
- Android:使用ViewPager实现左右滑动切换图片(图上有点点)
- android利用多线程加载图片【不使用第三方库】
- Android使用VideoView和MediaController播放网络视频(包括横竖排切换的处理)
- Glide 使用心得-看视频收藏的图片