-1

我正在尝试在Async执行后更新主线程 UI。我试图通过更新它onPostExecute并获取NullPointerException.

这是我的课

public class UncheckGuestArrayAdapter extends ArrayAdapter<UncheckGuestObj> {
    private final Activity thisContext;
    private ArrayList<UncheckGuestObj> guest = new ArrayList<UncheckGuestObj>();

    // String event_id;
    private String guest_id;

    // TODO to ask about the checkin
    static class ViewHolder {
        public TextView guestName;
        public TextView guestEmail;
        public Button btnCheckIn;
    }

    public ViewHolder holder;

    private ViewHolder getHolder(View v) {
        ViewHolder holder = new ViewHolder();
        holder.guestName = (TextView) v.findViewById(R.id.tx_guest_name);
        holder.guestEmail = (TextView) v.findViewById(R.id.tx_guest_email);
        holder.btnCheckIn = (Button) v.findViewById(R.id.btnCheckIn);
        return holder;
    }

    public UncheckGuestArrayAdapter(Activity context,
            ArrayList<UncheckGuestObj> objects) {
        super(context, R.layout.row_guest_list, objects);
        this.thisContext = context;
        this.guest = objects;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        View vi = convertView;
        if (vi == null || vi.getTag() == null) {
            LayoutInflater inflater = (LayoutInflater) thisContext
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            vi = inflater.inflate(R.layout.row_guest_list, null);
            holder = getHolder(vi);
            vi.setTag(holder);
        } else {
            holder = (ViewHolder) vi.getTag();
        }

        holder.guestName.setText(guest.get(position).guestName);
        holder.guestEmail.setText(guest.get(position).guestEmail);
        holder.btnCheckIn.setText("Check In");
        // holder.btnCheckIn.setBackgroundColor(Color.GREEN);

        holder.btnCheckIn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("you clicked", "the item at [" + position + "] position");
                guest_id = guest.get(position).guestId;
                new CheckInAsync().execute();
            }
        });

        return vi;
    }

    // Check In Async Task for executing the POST Request
    public class CheckInAsync extends AsyncTask<Void, Void, Void> {

        ProgressDialog mProgressDialog;

        @Override
        protected Void doInBackground(Void... params) {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            // Create a new HttpClient and Post Header
            HttpClient httpclient = new DefaultHttpClient();

            try {

                URI uri = new URI(Constants.BASE_URL + "/events/"
                        + GuestListActivity.event_id + "/guests/" + guest_id);
                Log.e(getClass().getSimpleName(), uri.toString());
                HttpPost httppost = new HttpPost(uri);

                // Add your data
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
                        2);
                // nameValuePairs.add(new BasicNameValuePair("sk", SharePref
                // .getInstance(GetEventList.this).getSessionKey()));
                Context mContext = null;
                nameValuePairs.add(new BasicNameValuePair("sk", SharePref
                        .getInstance(mContext).getSessionKey()));
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                HttpResponse response = httpclient.execute(httppost);

                int response_code = response.getStatusLine().getStatusCode();
                // HttpEntity entity = response.getEntity();
                Log.i("response code", "" + response_code);

                if (response_code == 201) {
                    Log.e("checkin status", "Checkin done");
                }

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
            return null;
        }

        protected void onPostExecute(Void result) {
            mProgressDialog.dismiss();
            holder.btnCheckIn.setText(R.string.heavy_check_mark);
            holder.btnCheckIn.setBackgroundColor(Color.MAGENTA);
            Toast.makeText(getContext(), "Checked In!", Toast.LENGTH_SHORT)
                    .show();
        }
    }
}

例外是

08-23 18:56:16.192: E/AndroidRuntime(11077): FATAL EXCEPTION: main
08-23 18:56:16.192: E/AndroidRuntime(11077): java.lang.NullPointerException
08-23 18:56:16.192: E/AndroidRuntime(11077):    at com.example.example.adaptor.UncheckGuestArrayAdapter$CheckInAsync.onPostExecute(UncheckGuestArrayAdapter.java:166)
08-23 18:56:16.192: E/AndroidRuntime(11077):    at com.example.example.UncheckGuestArrayAdapter$CheckInAsync.onPostExecute(UncheckGuestArrayAdapter.java:1)
08-23 18:56:16.192: E/AndroidRuntime(11077):    at android.os.AsyncTask.finish(AsyncTask.java:631)
08-23 18:56:16.192: E/AndroidRuntime(11077):    at android.os.AsyncTask.access$600(AsyncTask.java:177)

行号 166 是线路输入onPostExecute

        holder.btnCheckIn.setText(R.string.heavy_check_mark);
        holder.btnCheckIn.setBackgroundColor(Color.MAGENTA);

我做错了什么?

4

4 回答 4

1

试试下面

   ViewHolder holder;
    if (vi == null || vi.getTag() == null) {
       holder = new ViewHolder();
        LayoutInflater inflater = (LayoutInflater) thisContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        vi = inflater.inflate(R.layout.row_guest_list, null); 
        holder.guestName = (TextView) v.findViewById(R.id.tx_guest_name);
        holder.guestEmail = (TextView) v.findViewById(R.id.tx_guest_email);
        holder.btnCheckIn = (Button) v.findViewById(R.id.btnCheckIn);
        holder = getHolder(vi);
        vi.setTag(holder);
    } else {
        holder = (ViewHolder) vi.getTag();
    }
    .....

您还需要遵循 Doctoror Drive 的建议

您没有参考视图的。因此,当您尝试更新视图时,onPostExecute您会得到NullPointerException.

    holder.btnCheckIn.setText(R.string.heavy_check_mark);
    holder.btnCheckIn.setBackgroundColor(Color.MAGENTA);
于 2013-08-23T12:39:13.553 回答
1

我认为对于您的 ProgressDialog null 和异步 onPreExecute 方法覆盖实现并解决您的异常,

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog = ProgressDialog.show(YourActivityName.this, "wait", "loading");
    }
于 2013-08-23T12:38:52.897 回答
1

Holder 对象不能是成员,因为它对应于单个项目。而且您没有分配成员值,而是分配了本地 ViewHolder 。这是它应该如何工作的。移除 ViewHolder 成员,

公共 ViewHolder 持有者;

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        // ...
        // copy from original post
        // ...

        holder.btnCheckIn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("you clicked", "the item at [" + position + "] position");
                guest_id = guest.get(position).guestId;
                new CheckInAsync(holder).execute();
            }
        });

        return vi;
    }

    // Check In Async Task for executing the POST Request
    public final class CheckInAsync extends AsyncTask<Void, Void, Void> {

        private ProgressDialog mProgressDialog;
        private final ViewHolder holder;

        CheckInAsync(ViewHolder holder) {
            this.holder = holder;
        }

        @Override
        protected Void doInBackground(Void... params) {
              // copy from original post
        }

        protected void onPostExecute(Void result) {
            this.mProgressDialog.dismiss();
            this.holder.btnCheckIn.setText(R.string.heavy_check_mark);
            this.holder.btnCheckIn.setBackgroundColor(Color.MAGENTA);
            Toast.makeText(getContext(), "Checked In!", Toast.LENGTH_SHORT)
                    .show();
        }
    }
于 2013-08-23T12:42:33.943 回答
0

该方法在不同的线程中运行,因此无法更新 UI。只有 UI 线程中的东西才能做到这一点。所以,在处理过程中如果要更新UI,必须调用publishProgress,然后UI线程会调用onProgressUpdate,这样就可以更新UI了。

请参阅此线程以获得很好的解释:

从 AsyncTask 更新 UI

虽然这仍然有效,但我错过了 NullPointer 异常。t 可能没有像上面所说的那样被初始化。

于 2013-08-23T12:39:26.890 回答