致命异常 - 从服务器下载文件后开始播放视频

时间:2013-02-20 15:21:09

标签: android

我从服务器下载文件,然后将它们保存在内部。一旦我想播放视频,该应用就会破坏此错误日志

当它到达这一行时它会像人类一样破坏:或者在它之后,即使我删除了这一行

videoView.setVisibility(View.VISIBLE);




02-20 17:18:29.533: I/media player(26499): play media!
02-20 17:18:29.533: I/FILENAME(26499): video_tvr_webtrailer2.mp4
02-20 17:18:29.533: I/media player(26499): play video!
02-20 17:18:29.533: W/dalvikvm(26499): threadid=11: thread exiting with uncaught exception (group=0x40bf31f8)
02-20 17:18:29.533: E/AndroidRuntime(26499): FATAL EXCEPTION: Thread-7014
02-20 17:18:29.533: E/AndroidRuntime(26499): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
02-20 17:18:29.533: E/AndroidRuntime(26499):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4142)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:762)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at android.view.View.requestLayout(View.java:12727)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at android.view.View.requestLayout(View.java:12727)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at android.view.View.requestLayout(View.java:12727)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at android.view.View.requestLayout(View.java:12727)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at android.view.View.requestLayout(View.java:12727)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at android.view.View.setFlags(View.java:6767)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at android.view.View.setVisibility(View.java:4664)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at android.view.SurfaceView.setVisibility(SurfaceView.java:235)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at com.example.tvrplayer.MainActivity.playMedia(MainActivity.java:163)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at com.example.tvrplayer.MainActivity.createPlayList(MainActivity.java:184)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at com.example.tvrplayer.MainActivity.access$1(MainActivity.java:170)
02-20 17:18:29.533: E/AndroidRuntime(26499):    at com.example.tvrplayer.MainActivity$2.run(MainActivity.java:228)
02-20 17:18:34.572: D/OpenGLRenderer(26499): Flushing caches (mode 0)
02-20 17:18:36.291: D/OpenGLRenderer(26499): Flushing caches (mode 1)

这是我的代码:

package com.example.tvrplayer;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.DateFormat.Field;
import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.AssetFileDescriptor;
import android.graphics.drawable.AnimationDrawable;
import android.widget.ImageView;
import android.widget.VideoView;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;

public class MainActivity extends Activity implements OnCompletionListener {

    int playListIndex;
    int currentMedia;
    String mediaName;
    ArrayList<Integer> playList = new ArrayList<Integer>();
    File[] filelist;
    private VideoView videoView;
    private ImageView imageView;
    Uri mediaPath;
    private Handler mHandler = new Handler();

//  Get this shit from login!
    public String channelid = "5e6d-e673-46b1-9ffd-a16600d58fc9";
    public String username = "sd@ere.co";
    public String linkid = "70sd3f-e054-4f33-9b6b-a16600d3f7d7";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        File mediadir = getDir("tvr", Context.MODE_PRIVATE);
//        filelist = mediadir.listFiles();
        try {
            getProgramList();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

//       Delete all files in folder
        if (mediadir.isDirectory()) {
            String[] children = mediadir.list();
            for (int i = 0; i < children.length; i++) {
                new File(mediadir, children[i]).delete();
            }
        }

//        videoView = (VideoView) findViewById(R.id.videoView);
//      videoView.setVisibility(View.VISIBLE);
//      videoView.setOnCompletionListener(this);
//      String path = "android.resource://" + getPackageName() + "/" + R.raw.tvr_webtrailer2;
//      Uri uri = Uri.parse(path);
//      videoView.setVideoURI(uri);
//      videoView.start();


//      currentMedia = 1;
//      createPlayList(this);
//      try {
//          getProgramList(this);
//      } catch (IOException e) {
//          e.printStackTrace();
//      } catch (JSONException e) {
//          e.printStackTrace();
//      }
//      are there any files? if not download some, still not? keep checking every few seconds.



//      try {
//          getProgramList(this);
//      } catch (IOException e1) {
//          // TODO Auto-generated catch block
//          e1.printStackTrace();
//      } catch (JSONException e1) {
//          // TODO Auto-generated catch block
//          e1.printStackTrace();
//      }
//      createPlayList(this);
//      currentMedia = 1;
//      try {
////            
//          playMedia(this, currentMedia);
//      } catch (IOException e) {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//      }
    }
    @Override
    public void onCompletion(MediaPlayer mp) {
        Log.i("media player", "play next please!");
        if (mp != null) {
            videoView.setVisibility(View.GONE);
        }
//      play next video
        currentMedia++;
        if (currentMedia > playList.size() - 1) {
            currentMedia = 0;
        }
        Log.d("MEDIA_COUNTER", String.format("%d", currentMedia));
        try {
            playMedia(currentMedia);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    private void playMedia(int playListIndex) throws IOException {
        Log.i("media player", "play media!");
//      int resourceID = filelist.get(playListIndex); // This is the resource id
//      String path = "android.resource://" + getPackageName() + "/" + resourceID;
        String path = filelist[playListIndex].getAbsolutePath();
        final Uri uri = Uri.parse(path);
        String filename = filelist[playListIndex].getName();
        Log.i("FILENAME",filename);
        if (filename.contains("image")) {
            imageView = (ImageView)findViewById(R.id.imageView);
            imageView.setVisibility(View.VISIBLE);
//          imageView.setImageURI(uri);
            mHandler.postDelayed(new Runnable() {
                public void run() {
                    imageView.setVisibility(View.GONE);
                    imageView.setImageURI(uri);
                    onCompletion(null);
                }
            }, 3000);
        } else if (filename.contains("video")) {
            Log.i("media player", "play video!");
            videoView = (VideoView) findViewById(R.id.videoView);
            videoView.setVisibility(View.VISIBLE);
            videoView.setOnCompletionListener(this);
            videoView.setVideoPath(path);
            videoView.start();
        }
    }

    private void createPlayList(Context context) {
        ContextWrapper cw = new ContextWrapper(context);
        File mediadir = cw.getDir("tvr", Context.MODE_PRIVATE);
        filelist = mediadir.listFiles();
        if (filelist != null)
        {
            for ( int i = 0;i<filelist.length;i++)
            {
               Log.i("FOKKER", filelist[i].getName());
               Log.i("FOKKER", filelist[i].getAbsolutePath());
            }
        }
        currentMedia = 0;
        try {
            playMedia(currentMedia);
        } catch (IOException e) {
            e.printStackTrace();
        }

//      java.lang.reflect.Field[] fields = R.raw.class.getFields();
//      for(java.lang.reflect.Field f : fields)
//      try {
//          playList.add(f.getInt(null));
//          } catch (IllegalArgumentException e) {
//          } catch (IllegalAccessException e) { }      

    }

    private void downloadMedia() throws IOException, JSONException {
        getProgramList();
    }

    private void getProgramList () throws IOException, JSONException {
        Thread thread = new Thread() {
            @Override
            public void run() {
                ContextWrapper cw = new ContextWrapper(getBaseContext());
                File mediadir = cw.getDir("tvr", Context.MODE_PRIVATE);
                JSONArray json = Json.getJson("http://192.168.2.136:8080/rest/program/"+ linkid +"/"+ username +"/" + channelid, "GET");
                try {
                    for (int i=0; i < json.length(); i++) { 
                        JSONObject json_data = json.getJSONObject(i);
                        String name = json_data.getString("Name").toLowerCase();
                        name = name.replace("-", "_");
                        if (name.contains("mp4")) {
                            name = "/video_"+name;
                        } else if (name.contains("png") || name.contains("jpg") || name.contains("jpeg")) {
                            name = "/image_"+name;
                        }
                        File file = new File(mediadir, name);
                        if(file.exists()) {} else {
                            download(this, name, "http://192.168.2.136:8080/rest/transfer/"+ linkid +"/"+ username +"/" + json_data.getString("ID"));
                        }
                    }
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                createPlayList(cw);
            }

            private void download(Thread thread, String name, String urlString) {   
                File mediadir = getDir("tvr", Context.MODE_PRIVATE);
                try {
                    URL url = new URL(urlString);
                    URLConnection conexion = url.openConnection();
                    conexion.connect();
                    int lenghtOfFile = conexion.getContentLength();
                    InputStream is = url.openStream();
                    Log.d("DOWNLOAD NAME",name);
                    FileOutputStream fos = new FileOutputStream(mediadir+name);
                    byte data[] = new byte[1024];
                    int count = 0;
                    long total = 0;
                    int progress = 0;
                    while ((count=is.read(data)) != -1){
                        total += count;
                        int progress_temp = (int)total*100/lenghtOfFile;
                        if(progress_temp%10 == 0 && progress != progress_temp){
                            progress = progress_temp;
                        }
                        fos.write(data, 0, count);
                    }
                    is.close();
                    fos.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    Log.e("DOWNLOAD", e.toString());
                }
            } 
        };
        thread.start();
    }
}

2 个答案:

答案 0 :(得分:1)

这意味着从您的线程中,您似乎触摸或使用您的ui中的视图。 我不确定它会是什么,我需要好好看看。

最好的办法是将所有UI内容保留在线程之外。

答案 1 :(得分:1)

试试这个:

MainActivity.this.runOnUiThread(new Runnable()
{

 public void run()
 {
 Log.i("media player", "play video!");
            videoView = (VideoView) findViewById(R.id.videoView);
            videoView.setVisibility(View.VISIBLE);
            videoView.setOnCompletionListener(this);
            videoView.setVideoPath(path);
            videoView.start();
 }

});

如果它有效,那么你可能想尝试重构一下你的代码,以使其更好。