问题:
在连接成功后可以安全退出视频查看,当正在连接时点击后退按钮,应用会出现卡死想象,请大家指教,这个问题困扰好几天了。
activity部分代码:
JNI文件如下,只列出连接和退出摄像头的代码:
在连接成功后可以安全退出视频查看,当正在连接时点击后退按钮,应用会出现卡死想象,请大家指教,这个问题困扰好几天了。
activity部分代码:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle("温馨提示");
builder.setMessage("确定退出视频监控吗?");
builder.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
onBackPressed();
}
});
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create();
builder.show();
return false;
}
public void onBackPressed() {
try {
if (this.videoView.getStatus() == 1){
videoView.logoutDevice();
this.videoView.stopVideo();
if(videoThread != null){
videoThread.interrupt();
videoThread = null;
}
}
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
class VideoView extends View implements Runnable {
ByteBuffer buffer;
final int h = 288;
ImageButton ibutStop;
ImageButton ibutdown;
ImageButton ibutzoomin;
ImageButton ibutleft;
ImageButton ibutpic;
ImageButton ibutzoomout;
ImageButton ibutright;
ImageButton ibutup;
private int initial = 0;
private Bitmap mBitmap;
byte[] pixel = new byte[202752];
Bitmap resizedBitmap;
private int step = 0;
private boolean takepic = false;
Bitmap temp;
private Video video;
Bitmap videoBit = null;
final int w = 352;
static {
System.loadLibrary("Kernel");
}
public VideoView(Context paramContext, AttributeSet paramAttributeSet) {
super(paramContext, paramAttributeSet);
}
public native int status();
public native int connection(String paramString, int paramInt);
public native int loginDevice(String paramString1, String paramString2);
public native int liveVideo(int paramInt, Object paramObject);
public native int InitDecoder();
public native int UninitDecoder();
public native int changeChannel(int paramInt);
public native int connectionStatus();
public native int sendAutoPTZ(int paramInt1, int paramInt2);
public native int sendPTZCmd(int paramInt1, int paramInt2);
public native int stopVideo();
public native int logoutDevice();
public native int nextChannel(int paramInt);
public native int previousChannel(int paramInt);
public int getStatus() {
return status();
}
protected void onDraw(Canvas paramCanvas) {
try {
super.onDraw(paramCanvas);
if ((this.initial != 0) && (status() != 0)) {
videoBit = Bitmap.createBitmap(352, 288, Bitmap.Config.RGB_565);
buffer = ByteBuffer.wrap(this.pixel);
this.videoBit.copyPixelsFromBuffer(this.buffer);
if (this.takepic) {
saveBitmap2file(this.videoBit);
Toast.makeText(getContext(), "截图保存成功", 3000).show();
this.takepic = false;
}
Rect localRect1 = new Rect(0, 0, 352, 288);
Rect localRect2 = new Rect(0, 0, VideoActivity.viewWidth,
VideoActivity.viewHeight);
paramCanvas.drawBitmap(this.videoBit, localRect1, localRect2,
null);
}
int i = -10 + VideoActivity.viewHeight;
if (this.step == 0) {
Paint localPaint1 = new Paint();
localPaint1.setColor(Color.BLUE);
paramCanvas.drawText("正在连接前端设备, 请稍等..... ", 10, i, localPaint1);
}
if (this.step == 1) {
Paint localPaint2 = new Paint();
localPaint2.setColor(Color.GREEN);
paramCanvas.drawText("成功连接到前端设备 ", 10, i, localPaint2);
}
if (this.step == 2) {
Paint localPaint3 = new Paint();
localPaint3.setColor(Color.RED);
paramCanvas.drawText("连接前端设备失败 ", 10, i, localPaint3);
}
if (this.step == 3) {
Paint localPaint4 = new Paint();
localPaint4.setColor(Color.GREEN);
paramCanvas.drawText("登录前端设备成功 ", 10, i, localPaint4);
}
if (this.step == 4) {
Paint localPaint5 = new Paint();
localPaint5.setColor(Color.RED);
paramCanvas.drawText("传输实施视频失败 ", 10, i, localPaint5);
}
if (this.step == 5) {
Paint localPaint6 = new Paint();
localPaint6.setColor(Color.GREEN);
paramCanvas.drawText("正在传输实时视频", 10, i, localPaint6);
}
} catch (Exception e) {
// TODO: handle exception
}
}
public void run() {
try {
int result = -1;
result = connection(this.video.getIp(),
Integer.valueOf(this.video.getTp()));
System.out.println("connection ............" + this.video.getIp()
+ " " + this.video.getTp());
// result = connection("192.168.1.100",6036);
System.out.println("connection ............" + result);
if (result == 0) {
this.step = 2;
updateView();
return;
}
System.out.println(this.video.getUn() + "!!!!!!!!!!!!!!!!!!!!!!!!!"
+ this.video.getPw());
result = loginDevice(this.video.getUn(), this.video.getPw());
if (result == 1) {
step = 3;
updateView();
result = liveVideo(this.video.getCh(), pixel);
if (result != 1) {
step = 4;
updateView();
stopVideo();
return;
} else {
step = 5;
updateView();
}
} else {
return;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
buffer = null;
videoBit = null;
resizedBitmap = null;
temp = null;
System.gc();
}
}
boolean saveBitmap2file(Bitmap paramBitmap) {
Bitmap.CompressFormat localCompressFormat = Bitmap.CompressFormat.JPEG;
//.../storage/emulated/0/hanrun/
String str1 = Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator + "hanrun" + File.separator;
File localFile1 = new File(str1);
if (!localFile1.exists()) {
localFile1.mkdir();
}
Date localDate = new Date();
String str2 = new SimpleDateFormat("MMddkkmmss").format(localDate);
File localFile2 = new File(str1 + this.video.getTp() + str2 + ".jpg");
FileOutputStream localFileOutputStream;
try {
localFileOutputStream = new FileOutputStream(localFile2);
boolean bool2 = paramBitmap.compress(localCompressFormat, 100,
localFileOutputStream);
return bool2;
} catch (IOException localIOException2) {
localIOException2.printStackTrace();
return false;
}
}
public void setTakepic(boolean paramBoolean) {
this.takepic = paramBoolean;
}
public void setVideo(Video paramVideo) {
this.video = paramVideo;
}
public void updateView() {
postInvalidate();
this.initial = 1;
}
}
JNI文件如下,只列出连接和退出摄像头的代码:
JNIEXPORT jint JNICALL Java_com_handlerun_view_VideoView_connection
(JNIEnv *env, jobject thiz, jstring ip,jint port)
{
status = 1;
m_DeviceAddr.sin_family = AF_INET;
m_DeviceAddr.sin_port = htons(port);
char *m_ip = (char*)env->GetStringUTFChars(ip, NULL);
m_DeviceAddr.sin_addr.s_addr = inet_addr(m_ip);
sk.socket = socket(AF_INET,SOCK_STREAM,0);
if(sk.socket == SOCKET_ERROR)
{
status =0;
return 0;
}
//设置为非阻塞模式
unsigned long ul = 1;
result = ioctl(sk.socket, FIONBIO, &ul);
if(result == SOCKET_ERROR)
{
__android_log_print(ANDROID_LOG_ERROR,"Tag", " ioctl FIONBIO error :%d \n", result );
status = 0;
return 0;
}
//连接到服务器
int error;
result = connect(sk.socket,(struct sockaddr*)&m_DeviceAddr,sizeof(struct sockaddr));
if(result != -1 )
{
__android_log_print(ANDROID_LOG_ERROR,"Tag", "socket connect error :%d \n", result );
status = 0;
return 0;
}
//检测连接状态
if(errno != EINPROGRESS)
{
__android_log_print(ANDROID_LOG_ERROR,"Tag", "socket earn EINPROGRESS :%d \n", errno );
close(sk.socket);
status = 0;
return 0;
}
struct timeval tv;
fd_set writefds;
tv.tv_sec = 5;
tv.tv_usec = 0;
FD_ZERO(&writefds);
FD_SET(sk.socket, &writefds);
result = select(sk.socket+1,NULL,&writefds,NULL,&tv);
// 连接超时
if(result==0)
{
__android_log_print(ANDROID_LOG_ERROR,"Tag", " select error :%d \n", result );
close(sk.socket);
status = 0;
return 0;
}
//穿透防火墙
int len = sizeof(int);
result = getsockopt(sk.socket, SOL_SOCKET, SO_ERROR, &error, &len);
if(result!=0)
{
__android_log_print(ANDROID_LOG_ERROR,"Tag", " getsockopt error :%d \n", errno );
close(sk.socket);
status = 0;
return 0;
}
memset(buf,0,200);
result = ReceiveData(sk.socket,m_DeviceTypeInfo,64,20);
if(result != 64)
{
close(sk.socket);
status = 0;
return 0;
}
netprotrocolver = *((unsigned long*)m_DeviceTypeInfo+3);
__android_log_write(ANDROID_LOG_ERROR,"Tag","stopVideo ----hrsst stop over ------ ............... ");
return 1;
}
JNIEXPORT jint JNICALL Java_com_handlerun_view_VideoView_stopVideo
(JNIEnv *env, jobject thiz)
{
memset(&dataHead,0,dataHead_Size);
memset(&packCMD,0,packCmd_Size);
dataHead.HeadFlag = '1111';
dataHead.lLen = packCmd_Size;
packCMD.cmdType = CMD_REQUEST_LOGOUT;
packCMD.dataLen = 0;
result = SendData(sk.socket,(char*)&dataHead,dataHead_Size,10);
result = SendData(sk.socket,(char*)&packCMD,packCmd_Size,10);
result = shutdown(sk.socket,SHUT_RDWR);
close(sk.socket);
__android_log_write(ANDROID_LOG_ERROR,"Tag","stopVideo stop over ............... ");
status = 0 ;
return 1;
}