Эмулятор зависает при загрузке

1

Я пытаюсь создать простое приложение для загрузки и воспроизведения музыкального файла. Я сделал код, но, пытаясь его протестировать, приложение замерзает и показывает, что "Тайм-аут запуска истек, отказавшись от блокировки". Если у кого-то есть идея, не могли бы вы дать мне небольшой совет? Ниже мой код.

Кстати, файл образца, который я пытаюсь загрузить, имеет размер 9.1MB.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    try {
        setDataSource("http://cfs.tistory.com/custom/blog/66/661632/skin/images/Believe.mp3");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private void setDataSource(String path) throws IOException {        

    URL url = new URL(path);
    HttpURLConnection cn = (HttpURLConnection) url.openConnection();
    cn.setRequestMethod("GET");
    cn.setDoOutput(true);
    cn.connect();

    String file_path = Environment.getExternalStorageDirectory()+"/download/";
    String fileName = "Temp.wav";
    File file = new File(file_path);
    file.mkdir();

    InputStream is = cn.getInputStream();
    File output_file = new File(file, fileName);
    FileOutputStream fos = new FileOutputStream(output_file);

    byte[] buffer = new byte[4096];
    int read = 0;

    while ((read = is.read(buffer)) > 0){
        fos.write(buffer, 0, read);
    }
    is.close();
    fos.close();

    mp = new MediaPlayer();
    mp.setDataSource(file_path+fileName);
    mp.prepare();
    mp.start();

}

}

** Модифицировано: ** Джастин научил меня, если я просто положил его onCreate(), тогда это вызывает проблему. Теперь я использую кнопку с потоком, но есть еще одна проблема, которая говорит, что только исходный поток, создавший иерархию представлений, может коснуться его представлений и, похоже, что это происходит в 'fos.close'. Если кто-нибудь знает, что делать, не могли бы вы мне помочь?

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    tv = (TextView) findViewById(R.id.tv1);
    tv2 = (TextView) findViewById(R.id.tv2);
    tv.setText(Environment.getExternalStorageDirectory()+"/download/");

    Button btn = (Button) findViewById(R.id.button1);
    btn.setOnClickListener(new OnClickListener(){

        public void onClick(View v) {
            // TODO Auto-generated method stub
            Thread thread;
            Runnable r = new Runnable(){
                public void run(){
                    try {
                        setDataSource("http://cfs.tistory.com/custom/blog/66/661632/skin/images/Believe.mp3");
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }                       
                }
            };
            thread = new Thread(r);
            thread.start();

        }

    });
}

** Сообщения об ошибках: **


07-15 04:31:45.321: ERROR/AndroidRuntime(313): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
  • 0
    Спасибо джастин и анил
Теги:

2 ответа

1
Лучший ответ

Проблема в том, что ваш метод блокирует поток пользовательского интерфейса в течение длительного периода времени, и поэтому Android является принудительным закрытием приложения.

Попробуйте запустить длительный процесс в фоновом потоке в onCreateMethod(), а затем обновите интерфейс после его завершения.

Лучший способ узнать, как применять многопоточность, - это фактически просмотреть один из приложений Google, которые его используют. Вот цитата из первой ссылки.

"We highly recommend reading the source code of Shelves to see how to 
 persist tasks across configuration changes and how to cancel them 
 properly when the activity is destroyed."

Обновление: вы должны переместить медиаплеер обратно в поток пользовательского интерфейса и запустить фоновый поток, а затем обновить строку, которая передает медиаплеер, когда он закончит. Возможно, вам понадобится рефакторинг для использования задачи Async и переместите создание медиаплеера в onPostExecute(). Вы можете остановиться здесь и поэкспериментировать с Async Task и посмотреть, как приложение Shelves выполняет многопоточность.

Вы можете найти ссылки на приложение "Полки" в первом URL-адресе, который я поставил выше (в нижней части страницы).

  • 0
    Привет джастин Спасибо за ваш ответ. В таком случае, дадите ли вы мне знать, где я могу поместить этот метод 'setDataSource'?
  • 0
    Спасибо за вашу большую помощь, Джастин. Теперь я вижу, что оно не замораживает мое приложение, но все еще имеет проблему тайм-аута. Если вы не возражаете, не могли бы вы помочь мне немного больше? Скоро через две минуты я выложу модифицированный код по основному вопросу.
Показать ещё 1 комментарий
0

призвание. setDataSource как это

В вашей деятельности сделайте один обработчик, чтобы получить контроль, когда музыкальный файл был загружен.

Handler h1 = new Handler(){
   public void handleMessage(Message msg){
      // put the check here to see 
   }
};

new Thread(new Runnable(){

 public void run(){
   // set your datasource here 

   // back to your handler

}
}){
}.start();
  • 0
    Спасибо за ваш ответ success_anil. Я на самом деле создал свой собственный поток как раз раньше, и это, похоже, решило проблему, но теперь я столкнулся с другой проблемой, которая говорит, что «только оригинальный поток, создавший иерархию представлений, может касаться его представлений». Я добавил это к основному вопросу и хочу спросить вас, что, если вы не возражаете, не могли бы вы немного помочь мне решить эту проблему?
  • 0
    Вот почему я ответил с помощью обработчиков, что вы можете решить проблему лучше .... В приведенном выше коде, внутри метода run, сделайте это .. hi.sendMessage (h1.obtainMessage ()); и внутри handleMessage вашего обработчика проверьте, был ли файл загружен ... и используйте файл
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню