onItemClick变量的ClassCastException

时间:2015-07-30 01:39:54

标签: android string classcastexception pid onitemclick

我正在尝试在屏幕上显示的pid变量获得ClassCastException。我知道onclick位置的项目是一个转换为RunningAppProcessInfo的字符串,导致异常,但是我无法弄清楚如何在不使用它的情况下获取pid。

这是我的代码

  ActivityManager activityManager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
  List<RunningAppProcessInfo> list = activityManager.getRunningAppProcesses();

  ArrayList<String> info = new ArrayList<>();
  for (ActivityManager.RunningAppProcessInfo p : list) {
      info.add(p.processName);
  }

  ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, info);
  ListView listView = (ListView) findViewById(R.id.list);
  listView.setAdapter(adapter);

  listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
          int  uid = ((RunningAppProcessInfo)parent.getItemAtPosition(position)).pid;
          Toast.makeText(getApplicationContext(),uid,Toast.LENGTH_LONG).show();
        }
  });

2 个答案:

答案 0 :(得分:0)

嗯,不。您初始化适配器的方式,该项将是进程名称,而不是进程ID。它当然不会成为RunningAppProcessInfo的一个实例。如果您希望您的商品成为处理ID,请按以下步骤重新定义适配器:

ArrayList<Integer> info = new ArrayList<>();
for (ActivityManager.RunningAppProcessInfo p : list) {
    info.add(p.pid); // not p.processName
}

ArrayAdapter<Integer> adapter = new ArrayAdapter<>(this,
   android.R.layout.simple_list_item_1, info);

然后使用:

检索它
int uid = (Integer) parent.getItemAtPosition(position);

如果您需要两者,您必须定义自己的类,同时包含进程名称和ID:

class Info {
    final String processName;
    final int pid;
    Info(String processName, int pid) {
        this.processName = processName;
        this.pid = pid;
    }
    @Override
    public String toString() {
        return processName;
    }
}
ArrayList<Info> info = new ArrayList<>();
for (ActivityManager.RunningAppProcessInfo p : list) {
    info.add(new Info(p.processName, p.pid));
}

ArrayAdapter<Info> adapter = new ArrayAdapter<>(this,
   android.R.layout.simple_list_item_1, info);

并使用以下命令检索它:

int uid = ((Info)parent.getItemAtPosition(position)).pid;

你可能想写:

ArrayList<RunningAppProcessInfo> info = new ArrayList<>();
for (ActivityManager.RunningAppProcessInfo p : list) {
    info.add(p);
}

ArrayAdapter<RunningAppProcessInfo> adapter = new ArrayAdapter<>(this,
   android.R.layout.simple_list_item_1, info);

并保留原始检索代码,但不幸的是,RunningAppProcessInfo没有可用的toString()方法供适配器使用,因此您必须编写一个容器类这样或那样。

答案 1 :(得分:0)

parent.getItemAtPosition(position)实际上将返回您在ArrayAdapter构造函数中提供的列表项,因此它是一个String,当然当您尝试将此String转换为RunningAppProcessInfo时,您将获得classCastException。

我的建议是直接使用自定义适配器而不是ArrayAdapter。以下是我编写的示例代码供您参考:

public class ProcessSampleAdapter extends BaseAdapter {

private Context mContext;
private List<ActivityManager.RunningAppProcessInfo> mAppProcInfos;

public ProcessSampleAdapter(Context context, List<ActivityManager.RunningAppProcessInfo> list) {
    mContext = context;
    mAppProcInfos = list;
}

@Override
public int getCount() {
    return mAppProcInfos.size();
}

@Override
public Object getItem(int position) {
    return mAppProcInfos.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup root) {
    convertView = LayoutInflater.from(mContext).inflate(android.R.layout.simple_list_item_1, null);

    TextView textV = (TextView)convertView;
    textV.setText(mAppProcInfos.get(position).processName);

    return convertView;
}

}

顺便说一句,因为uid是一个int,所以不要直接将它提供给makeToast方法,否则不会显示uid,它会尝试查找id为uid的String资源。