我从我的应用收到该错误消息。但我认为我的ListView是从UIThread实现的,因为我有这段代码:
ListaOrdenesActivity.this.runOnUiThread(new Runnable() {
public void run() {
aAdapter=new SubnotsAdapter(c, 0, subnots);
setListAdapter(aAdapter);
aAdapter.notifyDataSetChanged();
}
});
这是设置适配器的活动:
public class ListaOrdenesActivity extends ListActivity {
Context c;
int id;
ArrayList<SubNotificacion> subnots=new ArrayList<SubNotificacion>();
Handler aHandler=new Handler();
SubnotsAdapter aAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listaordeneslayout);
c=getApplicationContext();
id=getIntent().getExtras().getInt("id");
General.campaignid=id;
for(int i=0;i<General.arraynot.size();i++){
if(General.arraynot.get(i).id==this.id){
subnots=General.arraynot.get(i).subnotificacion;
}
}
for (int i=0;i<subnots.size();i++){
General.ids.add(subnots.get(i).id);
}
ListaOrdenesActivity.this.runOnUiThread(new Runnable() {
public void run() {
aAdapter=new SubnotsAdapter(c, 0, subnots);
setListAdapter(aAdapter);
aAdapter.notifyDataSetChanged();
}
});
if(aAdapter!=null){
aAdapter.notifyDataSetChanged();
}
ImageView sos=(ImageView)findViewById(R.id.botonordenessos);
ImageView home=(ImageView)findViewById(R.id.botonordeneshome);
home.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent home=new Intent(c,HomeActivity.class);
startActivity(home);
}
});
}
}
适配器:
public class SubnotsAdapter extends ArrayAdapter {
ArrayList<SubNotificacion> objects=new ArrayList<SubNotificacion>();
Context context;
SimpleDateFormat format=new SimpleDateFormat("dd/MM/yyyy");
int idNoti;
int idSubnoti;
@Override
public int getCount() {
// TODO Auto-generated method stub
return objects.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return this.objects.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.subnotadapterlayout, null);
}
final SubNotificacion subnot=objects.get(position);
TextView lugar=(TextView)v.findViewById(R.id.textolugar);
lugar.setText(subnot.direccion);
TextView fecha=(TextView)v.findViewById(R.id.textofechasubnoti);
fecha.setText(format.format(subnot.dia).toString());
ImageView flecha=(ImageView)v.findViewById(R.id.flechasubnotadapter);
flecha.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent detalle=new Intent(context,SubnotDetailActivity.class);
detalle.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
detalle.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
detalle.putExtra("idsubnoti", subnot.id);
detalle.putExtra("idnoti", General.campaignid);
context.startActivity(detalle);
}
});
return v;
}
@SuppressWarnings("unchecked")
public SubnotsAdapter(Context context, int textViewResourceId,
ArrayList objects) {
super(context, textViewResourceId, objects);
this.objects=objects;
this.context=context;
}
}
如果我在UIThread中运行它...为什么我收到该错误消息?怎么解决?昨天我整整一天都遇到了这个问题...我认为今天会是一样的。
请帮忙!谢谢。
编辑:
完整的堆栈跟踪:
04-26 09:51:32.785: E/AndroidRuntime(30726): FATAL EXCEPTION: main
04-26 09:51:32.785: E/AndroidRuntime(30726): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(16908298, class android.widget.ListView) with Adapter(class com.publidirecta.vinceriazafata.SubnotsAdapter)]
04-26 09:51:32.785: E/AndroidRuntime(30726): at android.widget.ListView.layoutChildren(ListView.java:1514)
04-26 09:51:32.785: E/AndroidRuntime(30726): at android.widget.AbsListView$CheckForTap.run(AbsListView.java:2096)
04-26 09:51:32.785: E/AndroidRuntime(30726): at android.os.Handler.handleCallback(Handler.java:587)
04-26 09:51:32.785: E/AndroidRuntime(30726): at android.os.Handler.dispatchMessage(Handler.java:92)
04-26 09:51:32.785: E/AndroidRuntime(30726): at android.os.Looper.loop(Looper.java:130)
04-26 09:51:32.785: E/AndroidRuntime(30726): at android.app.ActivityThread.main(ActivityThread.java:3701)
04-26 09:51:32.785: E/AndroidRuntime(30726): at java.lang.reflect.Method.invokeNative(Native Method)
04-26 09:51:32.785: E/AndroidRuntime(30726): at java.lang.reflect.Method.invoke(Method.java:507)
04-26 09:51:32.785: E/AndroidRuntime(30726): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
04-26 09:51:32.785: E/AndroidRuntime(30726): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
04-26 09:51:32.785: E/AndroidRuntime(30726): at dalvik.system.NativeStart.main(Native Method)
因为它没有显示我的代码所在的位置,我猜它是在唯一的地方设置适配器...我把它放在UIThread ...
创建子标记的位置:
public class NotificationService extends Service {
private Timer timer=new Timer();
int icono=android.R.drawable.stat_sys_warning;
String estado="Ha recibido una nueva notificación";
long hora = System.currentTimeMillis();
Context c;
StringBuilder builder = new StringBuilder();
CustomHttpClient client = new CustomHttpClient();
String url;
String response="";
CharSequence titulo = "Oferta de trabajo!";
CharSequence descripcion = "Ha recibido una nueva oferta";
//Cada notificación del sistema tiene una id, en nuestro caso ésta será la id. Se utiliza para diferenciarla de las notificaciones del resto de
//aplicaciones, por ejemplo, para borrarla. En nuestro caso, eliminaremos la notificación cuando a) el usuario haga click en ella o b) el usuario haga click
//en el widget (Véase la clase StartJob.java)
public static int NOTIF_ID=5;
AppWidgetManager manager;
//String urljson;
ArrayList<SubNotificacion> listasub=new ArrayList<SubNotificacion>();
SubNotificacion subnot;
double salario;
String localidad;
String desc;
Notificacion not;
Notificacion check;
String nombre;
int id;
int duracion;
String respuesta="no";
String provincia;
Bitmap logo;
byte[] array;
String fechainicio;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
url=getString(R.string.host)+getString(R.string.appnamespace)+getString(R.string.urlcheckjob);//parametros: nombre:azafata valor:usuario
url=getString(R.string.host)+getString(R.string.appnamespace)+"personal/pendientes";
c=getApplicationContext();
//Método que lanza el servicio
lanzarServicio();
}
private void lanzarServicio() {
timer.scheduleAtFixedRate(
new TimerTask() {
@Override
public void run() {
//Log.i("LOGIN", "Lo que tenemos en respuesta: "+respuesta);
if(respuesta!="no"){
Log.i("LOGIN", "respuesta!=no");
//respuesta=lanzarPeticion();
check=parsearJSON(respuesta);
if(check.nombre!=null){
General.arraynot.add(check);
Log.i("LOGIN", "Campaña añadida al array de General");
General.arraytodas=General.arraynot;
//Configuramos el servicio de notificaciones
String ns = Context.NOTIFICATION_SERVICE;
Intent notIntent=new Intent(c, AlertsActivity.class);
PendingIntent contIntent = PendingIntent.getActivity(
c, 0, notIntent, 0);
Builder notif = new NotificationCompat.Builder(c);
synchronized (notif) {
notif.setContentIntent(contIntent)
.setWhen(System.currentTimeMillis())
.setTicker("Notification ticker")
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Vinceri")
.setContentText("Ha recibido una oferta de trabajo")
.setAutoCancel(true);
Notification notification = notif.build();
//get instance of NotificationManager
NotificationManager notificationmanager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//call notify method of NotificationManager to add this notification to android notification drawer..
notificationmanager.notify(0, notification);
//respuesta=lanzarPeticion();
}
}
}
Log.i("LOGIN", "Lanzamos la petición");
respuesta=lanzarPeticion();
}
}
,
0,
20000);
}
private String lanzarPeticion(){
Log.i("LOGIN", "Método lanzarPeticion()");
//En los parámetros, hemos de enviar el usuario, para que el server compruebe si hay trabajos para ese usuario en concreto
ArrayList <NameValuePair> parameters=new ArrayList<NameValuePair>();
//El usuario se ha almacenado en la clase estática "General"
parameters.add(new BasicNameValuePair("azafata", General.getUsuario()));
try {
//Lanzamos la petición
//lanzarServicio();
respuesta=CustomHttpClient.executeHttpPost(url, parameters);
respuesta= respuesta.replaceAll("\\s+","");
Log.i("LOGIN", "la respuesta: "+respuesta);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return respuesta;
}
private Notificacion parsearJSON(String json){
try {
JSONObject resp=new JSONObject(json);
Log.i("JSON", "Contenido del JSONObject: "+resp.toString());
JSONObject trabajos=new JSONObject(resp.getString("trabajos"));
JSONObject orden=new JSONObject(trabajos.getString("ordenTrabajo"));
desc=orden.getString("descripcion");
salario=orden.getDouble("salario");
localidad=orden.getString("localidad");
nombre=orden.getString("nombre");
id=orden.getInt("id");
duracion=orden.getInt("duracion");
provincia=orden.getString("provincia");
fechainicio=orden.getString("fechaInicio");
String jsonar=orden.getString("foto");
array=Base64.decode(jsonar, Base64.DEFAULT);
logo=BitmapFactory.decodeByteArray(array, 0, array.length);
JSONArray array=new JSONArray(orden.getString("subOrden"));
SimpleDateFormat recibido=new SimpleDateFormat("yyyy-MM-dd");
//SimpleDateFormat mostrar =new SimpleDateFormat("dd-MM-yyyy");
for(int i=0; i<array.length();i++){
JSONObject sub=array.getJSONObject(i);
if(sub!=null){
try {
subnot=new SubNotificacion(sub.getString("inicio"),
recibido.parse(sub.getString("fecha")),
sub.getString("direccion"),
sub.getInt("id"));
} catch (ParseException e) {
e.printStackTrace();
}
listasub.add(subnot);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
not=new Notificacion(desc, listasub, salario, localidad, nombre, id, duracion, provincia, logo, fechainicio);
return not;
}
protected void cambiarIcono() {
//Si el usuario está logueado, lanzamos el intent.
if(General.isIsloggedin()){
//Lanzamos un intent personalizado para nuestro widget, mediante un BroadCast que será interceptado por nuestro Widget provider (que no deja de ser un BroadcastReceiver)
Intent notIntent=new Intent("com.publidirecta.Azafatas.ACTUALIZAR_WIDGET");
c.sendBroadcast(notIntent);
}
}
}
和Subnotificacion类:
public class SubNotificacion {
String inicio;
Date dia;
String direccion;
int id;
public SubNotificacion(String inicio, Date dia, String direccion, int id) {
this.inicio = inicio;
this.dia = dia;
this.direccion = direccion;
this.id=id;
}
}
答案 0 :(得分:0)
尝试找出 subnots 类的“设置方法”。 “set methods”表示更改或修改对象数据的方法。
您正在对 SubnotsAdapter 中传递的数据进行一些更改。因此,找出您使用 subnots 数组列表的位置。