2

そこで、YouTube チャンネルから json データを取得して、YouTube アプリケーションを作成しようとしています。問題は、私がシングルスレッドのアプリケーションを書くのが得意だということです。しかし、マルチスレッドとなると、私はいつも洞察力を失います。

私はまだ学校でそれを学んでおらず、ほとんどのチュートリアルはゴミであるか、少なくとも私はそれを見つけました.

だから私がしたいのは、「GetVideos」クラスにスレッドを導入して、ビデオの取得中にアプリケーションの速度が低下しないようにすることです。ハンドラーとスレッドを使用する必要があることはわかっていますが、使用しようとするたびにアプリケーションがクラッシュします。手伝ってくれませんか?

public class GetVideos { //class that retrieves JSON data based on youtube username

private String channelName;
private HttpClient client; //client that gets info
private VideoLibrary lib;


public GetVideos(String channelName) {
    this.channelName = channelName;
    client = new DefaultHttpClient();
    lib = new VideoLibrary();
    fillData();
}

private void fillData() {
    try {
        final String URL = "http://gdata.youtube.com/feeds/api/users/" + channelName + "/uploads?v=2&alt=jsonc";
        HttpGet get = new HttpGet(URL);
        HttpResponse response = client.execute(get);
        String jsonString = EntityUtils.toString(response.getEntity());
        JSONObject json = new JSONObject(jsonString);
        JSONArray jsonArray = json.getJSONObject("data").getJSONArray("items");
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject items = jsonArray.getJSONObject(i);
            String title = items.getString("title");
            String thumbUrl = items.getJSONObject("thumbnail").getString("sqDefault");
            String url = items.getJSONObject("player").getString("default");
            lib.addVideo(new Video(title, url, thumbUrl));

        }

    } catch (JSONException e) {
        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
    } catch (ClientProtocolException e) {
        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
    } catch (IOException e) {
        e.printStackTrace();  
       }
   }

    public VideoLibrary getLib() {
         return lib;
    } 
 }

public class SxePhil extends Activity { //class that makes up the interactive end of
//the app, here the JSON data is put in a list 
private ListView list;
private GetVideos g;
private VideoLibrary videoLibrary;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sxephil);
    list = (ListView) findViewById(R.id.sxephilList);
    g = new GetVideos("sxephil");
    videoLibrary = g.getLib();

    ArrayList<String> titles = new ArrayList<String>();
    for (int i = 0; i < 25; i++) {
        titles.add(videoLibrary.getVideos().get(i).getTitle());
    }


       ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.simplerow, titles);
        list.setAdapter(adapter);
   }  
}

基本的に私が試したのは、ここで使用されているスレッドを実装することでした: http://blog.blundell-apps.com/show-youtube-user-videos-in-a-listview/

私のコードでは、このプロジェクトは古い SDK で構築されていたため、いわば最新化したいと考えていました。お金がある場所である GetYoutube*** クラスと MainActivity クラスを見てください

4

3 に答える 3

0

これは、AsyncTaskを使用して最も簡単に実行できます。このチュートリアルをチェックしてください。

http://android-developers.blogspot.com/2009/05/painless-threading.html

于 2012-08-23T21:50:38.273 に答える
0

AsyncTaskを使用するか、さらに良いことにLoaderを使用する必要があります。それらは自動的にトレッドを処理します

于 2012-08-23T21:41:53.233 に答える
0

最初 : 基本的なアドバイス (必ず覚えて従う必要があります)

  • クラス コンストラクターで処理を行うことはありません (これは OO の設計としては不適切です)。
  • 時間のかかるプロセスを Activity.onCreate メソッド (および一般に、UI スレッドによって実行されるすべてのメソッド、つまり onResume()、onClick() など) に残さないでください

mario と runor49 は正しかった: ここで AsyncTask を使用する必要があります (そしてhttp://developer.android.com/guide/components/processes-and-threads.html#WorkerThreadsを読んで理解する必要があります。そうでない場合は、読んでくださいまたね…)

基本的に、次のことを行う必要があります。

  1. onCreate は、「長い」処理 (ネットワークからデータをロードする) を含む別のスレッドを起動する必要があります。
  2. 完了したら、このスレッドは Activity.runOnUiThread(Runnable) を呼び出す必要があります。ここで、ランナブルがアダプターを作成し、それを ListView に割り当てます。

コードサンプルは次のとおりです。

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    loadDataInThread();
    }

private void loadDataInThread() {
    new Runnable() {            
        @Override
        public void run() {
            // LOAD DATA FROM NETWORK
            displayDataInUIThread(datas);
            }
        }.start();
    }       

private void displayDataInUIThread(final VideoLibrary data) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.simplerow, data);
            list.setAdapter(adapter);
        }
    });
}

これは非常に基本的な (そして失礼な) 方法であり、AsyncTask の方法 () の方がはるかに優れていますが、機能してコントラクトを満たす必要があります...

于 2012-08-23T21:43:16.287 に答える