0

そのグリッドに次の機能を追加しようとしたグリッドビューを作成しました。誰かが「次へ」をクリックすると、グリッドに新しい画像が読み込まれます。

私はロジックを作成し、何とか機能していますが、安定していません。アプリが停止することがあり、「次へ」をクリックすると次のページがスキップされることがあります (現在、ページ 0 にいて、「次へ」をクリックするとグリッドが更新され、ページ 1 ではなくページ 2 が表示されるとします)

私がやっていることは、画像の新しい URL のために http リクエストを php サーバーに送信する asynctask を作成したことです。次に、グリッドビューを更新し、新しい画像の URL から新しい画像を表示します。

コード

public class UserPage extends Activity {


ImageAdapter ia = new ImageAdapter(this);
GetResponse task = new GetResponse(0);
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.userpage);

    final GridView gridview = (GridView) findViewById(R.id.gridview);

    gridview.setAdapter(ia);
    gridview.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);

    Button nxt = (Button) findViewById(R.id.nextbuttongrid);
    nxt.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            // next page
            int i = Integer.parseInt(GetResponse.counter);
            i=i+1;
            GetResponse.counter = Integer.toString(i);
            String x = GetResponse.response;
            task.execute();
        //this is done so that the thread sleeps until the response variable value is updated  
            while(x.equals(GetResponse.response)==true){
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    System.out.println("Here in sleep..incre");
                } }
            change(gridview);
        }
    });

    Button pre = (Button) findViewById(R.id.previousbuttongrid);
    pre.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            // previous page
            int i = Integer.parseInt(GetResponse.counter);
            i=i-1;
            GetResponse.counter = Integer.toString(i);
            String x = GetResponse.response;
            task.execute();
           //this is done so that the thread sleeps until the response variable value is updated  
            while(x.equals(GetResponse.response)==true){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("Here in sleep.. decre");
            } }
            change(gridview);

        }
    });

    /**
     * On Click event for Single Gridview Item
     * */
     gridview.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View v,
                int position, long id) {

            // Sending image id to FullImage.java
            Intent i = new Intent(getApplicationContext(), FullImage.class);
            i.putExtra("id", position);
            startActivity(i);
        }
    });
}

void change(GridView gridview) {
    ia = new ImageAdapter(this);
    gridview.invalidateViews();
    gridview.setAdapter(ia);
}
}
public class GetResponse extends AsyncTask<Void, Void, Void> {

  public static String counter = "0";

  HttpPost httppost;
  StringBuffer buffer;
  HttpResponse response1;
  HttpClient httpclient;
  List<NameValuePair> nameValuePairs;

  public static String response;


    @Override
    protected Void doInBackground(Void... params) {

try {
    Log.d("response's Value == >", "Response previous " + response);
    httpclient=new DefaultHttpClient();
    httppost= new HttpPost(ServerAdressHere); 
    //add your data
    nameValuePairs = new ArrayList<NameValuePair>(3);

    nameValuePairs.add(new BasicNameValuePair("username",AndroidPHPConnectionDemo.userName)); 
    nameValuePairs.add(new BasicNameValuePair("password",AndroidPHPConnectionDemo.passWord));
    nameValuePairs.add(new BasicNameValuePair("count",counter));
    Log.d("Counter's Value == >", "Counter " + counter);
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    //Execute HTTP Post Request
    response1=httpclient.execute(httppost);
    ResponseHandler<String> responseHandler = new BasicResponseHandler();
    response = httpclient.execute(httppost, responseHandler);
    Log.d("response's Value == >", "Response after " + response);
}
    catch(Exception e){
        System.out.println("Exception Here"+e);
    }
  return null;

    }
   }
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private TextView txtUrl;
private String response;
public ImageView imageView;
public static String[] mThumbIds;

  public ImageAdapter(Context c) {
    mContext = c;
    this.response = GetResponse.response.trim();
    mThumbIds = response.split(",");
    }

private final Downloader imageDownloader = new Downloader(mContext);


public int getCount() {
    return mThumbIds.length;
}

public Object getItem(int position) {
    return mThumbIds[position];
}

public long getItemId(int position) {
    return mThumbIds[position].hashCode();
}

// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {

    if(convertView==null) {
        imageView = new ImageView(mContext);
        imageView.setLayoutParams(new GridView.LayoutParams(LayoutParams.MATCH_PARENT, 195));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(10, 10, 10, 10);
    }

    else {
         imageView = (ImageView) convertView;
         }

    imageDownloader.DisplayImage(mThumbIds[position], (ImageView) imageView);

    return imageView;
}

public Downloader getImageDownloader() {
    return imageDownloader;
}
}

次のグリッドビューのページ番号を php サーバーに伝えるリクエストで、「カウンター」変数 (静的および文字列型) が送信されます。したがって、サーバーはそのページ番号に関連付けられた画像の URL を送信します。

私が直面している問題は、「応答」変数が asynctask クラスによって更新される前にグリッドが更新されることです。だから私は System.sleep() を使用して、2行のコードの実行時間のギャップを取得しました。

"response" 変数 (静的および整数型) には、画像の URL が含まれます。

助けてください !さらに詳細が必要な場合は、お問い合わせください。

4

1 に答える 1

0

まず第一に、onClick メソッドのループ内の Thread.sleep は、これを行う適切な方法ではありません。asynctask の要点は、メイン スレッドのロックを回避することであり、Thread.sleep はまさにそれを行っています。

代わりに asynctask の onPostExecute を使用してください。

ただし、UIがおそらく数秒間フリーズしても、これは明らかに機能します(サーバーと接続は十分に高速です。そうしないと、ANRが発生します)。

その後、画像ダウンロードの件です。setAdapter(new Adapter...) を呼び出すことは、十分な方法のようです。

ステップバイステップのデバッグでどこまで進んだか?

  • イメージ ID リストを受け取りますLog.d("response's Value == >", "Response after " + response);か?
  • getView に到達した場合、mThumbIds[position] にあるはずの正しい url/id/string でそこに到達しますか?
  • もしそうなら、ダウンローダとは何ですか?どのように機能しますか?

好奇心から、なぜリクエストを 2 回実行するのですか? ( response1=httpclient.execute(httppost);)

編集

アプリが実際にクラッシュしていたことに言及するのは興味深いことでしたが、そうしなかったとは本当に信じられません。これは、「グリッドが更新されていない」とはまったく異なります。

必ず

A/ スタック トレースを読み取ります。

B/ 不明な場合は、Google で検索してください。

C/他に何を追加できるかわかりません(a task can be executed only once)

于 2013-04-08T16:18:48.413 に答える