完成从AsyncTask更新UI时出现NullPointer异常

时间:2013-08-23 12:35:21

标签: java android android-asynctask

我正在尝试在执行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 个答案:

答案 0 :(得分:1)

我认为你的ProgressDialog null和async onPreExecute方法覆盖实现并解决你的例外,

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog = ProgressDialog.show(YourActivityName.this, "wait", "loading");
    }

答案 1 :(得分: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);

答案 2 :(得分:1)

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

public ViewHolder holder;

    @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();
        }
    }

答案 3 :(得分:0)

该方法在不同的线程中运行,因此无法更新UI。只有UI线程中的东西才能做到这一点。因此,在处理期间如果要更新UI,则必须调用publishProgress,然后UI线程将调用onProgressUpdate,您可以在那里更新UI。

请参阅此主题以获得更好的解释:

来自AsyncTask的UpdateUI

虽然这仍然有效,但我错过了NullPointer异常。如上所述,可能没有初始化。