2011-07-15 5 views
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

ありがとう、Justin and anil – June

答えて

1

問題は、あなたの方法は、長期間UIスレッドをブロックしているので、Androidのアプリケーションを強制的に閉じているということです。

onCreateMethod()のバックグラウンドスレッドで長時間実行されているプロセスを起動し、終了したらUIを更新してください。

マルチスレッドを適用する方法を学ぶための最善の方法は、実際にそれを使用して、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." 

更新:あなたが戻ってUIスレッドにメディアプレーヤーを移動し、バックグラウンドスレッドの実行を持っているし、それが終了していますとき、メディアプレーヤーを供給した文字列を更新する必要があります。非同期タスクを使用し、メディアプレーヤーの作成をonPostExecute()に移動するには、リファクタリングが必要な場合があります。ここでやめて、非同期タスクを試して、Shelvesアプリがマルチスレッド化している様子を見てみてください。

Shelvesアプリケーションへのリンクは、上に示した最初のURL(ページの下部にあります)にあります。

+0

こんにちは、Justin。お返事をありがとうございます。この場合、この 'setDataSource'メソッドをどこに置くことができるか教えてください。 – June

+0

ジャスティンのお手伝いをありがとう。私は今、それが私のアプリをフリーズしていないが、まだタイムアウトの問題があることを参照してください。あなたが気にしないなら、もう少し私を助けてくれますか?私は2分で主題に関する修正されたコードをすぐにアップロードします。 – June

+0

私はジャスティンを手に入れました。あなたの説明をありがとう。私は今このトピックを閉じます – June

0

呼び出し。このようなsetDataSource

あなたの活動では、音楽ファイルがダウンロードされたときにコントロールを取得するハンドラを1つ作成します。

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ありがとう。私は実際に自分のスレッドを作成したばかりですが、問題を解決したようですが、「ビュー階層を作成した元のスレッドだけがそのビューに触れることができる」という別の問題が発生しました。私はこれを主な質問に加えました。あなたが気にしないなら、この問題を解決するためにもう少し手伝ってくださいますか? – June

+0

だからこそ、私はあなたが問題をより良く解決できるハンドラを使って答えました....上記のコードでは、内部で実行するメソッドがこれを行います.. hi.sendMessage(h1.obtainMessage());あなたのハンドラのhandleMessageの内部で、ファイルがダウンロードされているかどうかをチェックし、ファイルを使用してください。 –

+0

あなたの答えをもう一度いただきありがとうございます。可能であれば、私に恵まれますか?私はあなたのコードを実装しようとしましたが、それは私に文法エラーを次々と提供し、私が少し修正するのが難しいようです。私には完全なコードを作ることができますか? – June

関連する問題