0

カスタム onClick リスナー内から Intent で startActivity() を呼び出すと問題が発生します。コードは正常にコンパイルされますが、実行のその時点に到達すると、nullPointerException が発生します。

コード

private static class ProverbAdapter extends ArrayAdapter<String> {
    MainActivity ma;
    public ProverbAdapter(Context context, int layout, int resId, String[] items) {
        super(context, layout, resId, items);
        this.ma = new MainActivity();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        Context context = getContext();
        if(row == null) {
            row = LayoutInflater.from(context).inflate(R.layout.proverb_layout, parent, false);
        }

        String item = getItem(position);
        TextView proverbDate = (TextView)row.findViewById(R.id.proverb_date);
        TextView proverbText = (TextView)row.findViewById(R.id.proverb_content);
        String[] data = item.split("----");
        proverbDate.setText(data[0]);
        proverbText.setText(data[1]);

        ImageButton emailButton = (ImageButton)row.findViewById(R.id.emailButton);
        ImageButton twitterButton = (ImageButton)row.findViewById(R.id.twitterButton);
        ImageButton facebookButton = (ImageButton)row.findViewById(R.id.facebookButton);

        emailButton.setOnClickListener(this.ma.new ProverbOnClickListener(data[0], data[1], "email", context));
        twitterButton.setOnClickListener(this.ma.new ProverbOnClickListener(data[0], data[1], "twitter", context));
        facebookButton.setOnClickListener(this.ma.new ProverbOnClickListener(data[0], data[1], "facebook", context));

        return row;
    }
}

public class ProverbOnClickListener implements OnClickListener {

     String proverb_date, proverb_content, eventType;
     Context context;

     public ProverbOnClickListener(String proverb_date, String proverb_content, String eventType, Context context) {
          this.proverb_date = proverb_date;
          this.proverb_content = proverb_content;
          this.eventType = eventType;
          this.context = context;
     }

     @Override
     public void onClick(View v) {
         Toast.makeText(this.context, this.eventType + ": " + this.proverb_content, Toast.LENGTH_SHORT).show();
         if(this.eventType == "email") {
             Intent i = new Intent(Intent.ACTION_SEND);
                     i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             i.setType("message/rfc822");
             i.putExtra(Intent.EXTRA_EMAIL  , new String[]{"recipient@example.com"});
             i.putExtra(Intent.EXTRA_SUBJECT, "subject of email");
             i.putExtra(Intent.EXTRA_TEXT   , "body of email");
             try {
                 context.startActivity(Intent.createChooser(i, "Send mail..."));
             } catch (android.content.ActivityNotFoundException ex) {
                 Toast.makeText(this.context, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
             }
         }
     }

  }

例外

FATAL EXCEPTION: main android.util.AndroidRuntimeException: Activity コンテキストの外部から startActivity() を呼び出すには、FLAG_ACTIVITY_NEW_TASK フラグが必要です。これは本当にあなたが望むものですか?

コンパイラが提案したように新しいフラグを追加しましたが、それでも同じエラーでクラッシュします。

* *編集* ***

最初の応答のアドバイスに従った後、アダプターは次のようになります。

private static class ProverbAdapter extends ArrayAdapter<String> {
    Context context;
    public ProverbAdapter(Context context, int layout, int resId, String[] items) {
        super(context, layout, resId, items);
        this.context = context;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        if(row == null) {
            LayoutInflater li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = li.inflate(R.layout.proverb_layout, parent, false);
        }

        String item = getItem(position);
        TextView proverbDate = (TextView)row.findViewById(R.id.proverb_date);
        TextView proverbText = (TextView)row.findViewById(R.id.proverb_content);
        String[] data = item.split("----");
        proverbDate.setText(data[0]);
        proverbText.setText(data[1]);

        ImageButton emailButton = (ImageButton)row.findViewById(R.id.emailButton);
        ImageButton twitterButton = (ImageButton)row.findViewById(R.id.twitterButton);
        ImageButton facebookButton = (ImageButton)row.findViewById(R.id.facebookButton);

        emailButton.setOnClickListener(new ProverbOnClickListener(data[0], data[1], "email", context));
        twitterButton.setOnClickListener(new ProverbOnClickListener(data[0], data[1], "twitter", context));
        facebookButton.setOnClickListener(new ProverbOnClickListener(data[0], data[1], "facebook", context));

        return row;
    }
}

ただし、コンパイル エラーが発生します。

MainActivity の外側のインスタンス タイプにアクセスできません。

4

1 に答える 1

2

いくつかの変更を試してください

this.ma = new MainActivity(); //it is wrong

アクティビティをインスタンス化しない

このようにしてみてください

 Context context;
    public ProverbAdapter(Context context, int layout, int resId, String[] items) {
        super(context, layout, resId, items);
       this.context=context;
    }

コンテキストが必要な場合はいつでもこの変数コンテキストを使用してください

于 2013-03-07T15:15:26.100 に答える