3

私は Android 開発の初心者です。最初のアプリで作業していて、問題に遭遇しました。インターネットからいくつかの画像をダウンロードし、それらをアクティビティで表示する必要があります。画像がダウンロードされるまで UI に遅延があるため、マルチスレッドを使用する必要があります。

私はそれについてもっと読んで、最も簡単なのは AsyncTask だと思いますが、例外を受け取ります:Only the original thread that created a view hierarchy can touch its views.

私は助けが必要です。誰でも私を助けることができますか?コードは次のとおりです。

public class Main extends Activity{



protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Download download = new Download();
    download.execute(null);
}

private class Download extends AsyncTask<String, Void, String>{
    ImageButtonOverloaded[] imgView = new ImageButtonOverloaded[24];
    TextView[] textView = new TextView[24];
    @Override
    protected String doInBackground(String... params) {
        try{

            URL url = null;
            url = new URL(StaticClass.URL_HOST + "front_page_last_games_plaintext.php");
            URLConnection conn = url.openConnection();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;

            initCovers();
            int i = 0;
            Log.d("SYNC", "i = 0");
            while((line = reader.readLine()) != null){
                String gameInfo[] = line.split("<NEXT>");
                //Log.d("SYNC", gameInfo[0]);
                //Log.d("SYNC", gameInfo[1]);
                Drawable x = ImageOperations(Main.this, StaticClass.URL_HOST + "resize.php?imagine=" + gameInfo[0] ,"image.jpg");

                Log.d("SYNC", "in while");
                imgView[i].setImageDrawable(x);
                Log.d("SYNC", "in while");
                imgView[i].setGameID(gameInfo[0]);
                imgView[i].setOnClickListener(new OnClickListener() {

                    public void onClick(View v) {
                        ImageButtonOverloaded temp = (ImageButtonOverloaded) v;
                        Intent intent = new Intent(Main.this, Single.class);
                        intent.putExtra("ID", temp.getGameID());
                        startActivity(intent);

                    }
                });

                textView[i].setText(gameInfo[1]);
                textView[i].setGravity(Gravity.TOP);
                textView[i].setGravity(Gravity.CENTER_HORIZONTAL);
                textView[i].setTextColor(Color.WHITE);
                i++;
            }
        }catch(Exception ex){
            Log.d("SYNC", ex.getMessage());
        }
        return null;
    }
    private Drawable ImageOperations(Context ctx, String url, String saveFilename) {
        try {
            InputStream is = (InputStream) this.fetch(url);
            Drawable d = Drawable.createFromStream(is, "src");
            return d;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public Object fetch(String address) throws MalformedURLException,IOException {
        URL url = new URL(address);
        Object content = url.getContent();
        return content;
    }
    private void initCovers(){
        imgView[0] = (ImageButtonOverloaded) findViewById(R.id.imageButton1);
        imgView[1] = (ImageButtonOverloaded) findViewById(R.id.imageButton2);
        imgView[2] = (ImageButtonOverloaded) findViewById(R.id.imageButton3);
        imgView[3] = (ImageButtonOverloaded) findViewById(R.id.imageButton4);
        imgView[4] = (ImageButtonOverloaded) findViewById(R.id.imageButton5);
        imgView[5] = (ImageButtonOverloaded) findViewById(R.id.imageButton6);
        imgView[6] = (ImageButtonOverloaded) findViewById(R.id.imageButton7);
        imgView[7] = (ImageButtonOverloaded) findViewById(R.id.imageButton8);
        imgView[8] = (ImageButtonOverloaded) findViewById(R.id.imageButton9);
        imgView[9] = (ImageButtonOverloaded) findViewById(R.id.imageButton10);
        imgView[10] = (ImageButtonOverloaded) findViewById(R.id.imageButton11);
        imgView[11] = (ImageButtonOverloaded) findViewById(R.id.imageButton12);
        imgView[12] = (ImageButtonOverloaded) findViewById(R.id.imageButton13);
        imgView[13] = (ImageButtonOverloaded) findViewById(R.id.imageButton14);
        imgView[14] = (ImageButtonOverloaded) findViewById(R.id.imageButton15);
        imgView[15] = (ImageButtonOverloaded) findViewById(R.id.imageButton16);
        imgView[16] = (ImageButtonOverloaded) findViewById(R.id.imageButton17);
        imgView[17] = (ImageButtonOverloaded) findViewById(R.id.imageButton18);
        imgView[18] = (ImageButtonOverloaded) findViewById(R.id.imageButton19);
        imgView[19] = (ImageButtonOverloaded) findViewById(R.id.imageButton20);
        imgView[20] = (ImageButtonOverloaded) findViewById(R.id.imageButton21);
        imgView[21] = (ImageButtonOverloaded) findViewById(R.id.imageButton22);
        imgView[22] = (ImageButtonOverloaded) findViewById(R.id.imageButton23);
        imgView[23] = (ImageButtonOverloaded) findViewById(R.id.imageButton24);

        textView[0] = (TextView) findViewById(R.id.textView1);
        textView[1] = (TextView) findViewById(R.id.textView2);
        textView[2] = (TextView) findViewById(R.id.textView3);
        textView[3] = (TextView) findViewById(R.id.textView4);
        textView[4] = (TextView) findViewById(R.id.textView5);
        textView[5] = (TextView) findViewById(R.id.textView6);
        textView[6] = (TextView) findViewById(R.id.textView7);
        textView[7] = (TextView) findViewById(R.id.textView8);
        textView[8] = (TextView) findViewById(R.id.textView9);
        textView[9] = (TextView) findViewById(R.id.textView10);
        textView[10] = (TextView) findViewById(R.id.textView11);
        textView[11] = (TextView) findViewById(R.id.textView12);
        textView[12] = (TextView) findViewById(R.id.textView13);
        textView[13] = (TextView) findViewById(R.id.textView14);
        textView[14] = (TextView) findViewById(R.id.textView15);
        textView[15] = (TextView) findViewById(R.id.textView16);
        textView[16] = (TextView) findViewById(R.id.textView17);
        textView[17] = (TextView) findViewById(R.id.textView18);
        textView[18] = (TextView) findViewById(R.id.textView19);
        textView[19] = (TextView) findViewById(R.id.textView20);
        textView[20] = (TextView) findViewById(R.id.textView21);
        textView[21] = (TextView) findViewById(R.id.textView22);
        textView[22] = (TextView) findViewById(R.id.textView23);
        textView[23] = (TextView) findViewById(R.id.textView24);

    }
}}
4

1 に答える 1

5

doInBackgorund()非UIスレッドであり、その中のUI要素にアクセスすることはできません。doInBackground()内のコードは、レイアウトで定義されたUI要素にアクセスできない別の非UIスレッドで実行されます。また、インテントを介して別のアクティビティを呼び出すため、アクティビティはUIスレッドで実行されるため、UI以外のスレッド内から別のアクティビティを開始しないように常に注意する必要があります。

したがって、UI要素にアクセスするコードをdoInBackground()の内部から削除し、代わりにonPostExecute()、UIスレッドであり、doInBackground()がバックグラウンド処理を終了した後に呼び出される内部に配置します。

int i =0; // global variable
Drawable drawableArray []; // global array to store all the drawables 

doInBackground(String... params) {
        try{

            URL url = null;
            url = new URL(StaticClass.URL_HOST + "front_page_last_games_plaintext.php");
            URLConnection conn = url.openConnection();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;

            initCovers();
            while((line = reader.readLine()) != null){
                String gameInfo[] = line.split("<NEXT>");
                //Log.d("SYNC", gameInfo[0]);
                //Log.d("SYNC", gameInfo[1]);
                drawableArray[i] = ImageOperations(Main.this, StaticClass.URL_HOST + "resize.php?imagine=" + gameInfo[0] ,"image.jpg");
                i++;
}

onPostExecute()
{
   for(j=0;j<=i;j++)

                Log.d("SYNC", "in while");
                imgView[j].setImageDrawable(drawableArray[j]);
                Log.d("SYNC", "in while");
                imgView[j].setGameID(gameInfo[0]);
                imgView[j].setOnClickListener(new OnClickListener() {

                    public void onClick(View v) {
                        ImageButtonOverloaded temp = (ImageButtonOverloaded) v;
                        Intent intent = new Intent(Main.this, Single.class);
                        intent.putExtra("ID", temp.getGameID());
                        startActivity(intent);

                    }
                });

                textView[j].setText(gameInfo[1]);
                textView[j].setGravity(Gravity.TOP);
                textView[j].setGravity(Gravity.CENTER_HORIZONTAL);
                textView[j].setTextColor(Color.WHITE);
                j++;
            }
}

編集:@Luksprog@tolgapが指摘しているように、メインUIスレッドの画像処理部分は長い操作であり、UIが応答しなくなる可能性があります。したがって、バックグラウンドスレッドでも画像処理を実行してから、onPostExecute()を使用して、画像ビットマップを設定し、他のUI要素を更新することをお勧めします。グローバル配列を使用して、バックグラウンドで処理を実行し、onPostExecute()内のUIを更新することで、Drawableを格納します。

于 2012-10-06T19:17:34.253 に答える