2

У меня есть и приложение для Android, которое работает на android 4.0 отлично, но оно падает на Android 4.3 и 4.4. Я получаю это от LogCatApp crashes on android 4.0+

01-11 14:40:27.669: E/ACRA(25835): ACRA caught a IllegalStateException exception for quran. Building report. 
01-11 14:40:27.789: E/AndroidRuntime(25835): 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(2131099688, class android.widget.ListView) with Adapter(class quran.functions.PlaylistAdapter)] 

Вот мой код:

public class Playlist extends FragmentActivity { 

    private ListView list; 
    private Button manager, downloadAll; 
    private TextView reciter; 
    public static PlaylistAdapter adapter; 
    private ArrayList<Songs> songs; 
    private int RECITER_ID; 
    private String url, title, label; 
    private SlidingMenu slidingMenu; 
    private DatabaseHelper db; 
    private ImageView nowPlaying, back; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.playlist); 
     initWidgets(); 
     list.setOnItemClickListener(new OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> arg0, View arg1, 
        int position, long arg3) { 

       Intent intent = new Intent(Playlist.this, PlayerFinal.class); 
       intent.putExtra("songs", songs); 
       if (getIntent().getIntExtra("duaa", -1) == 115) 
        intent.putExtra("lang", 115); 
       intent.putExtra("position", position); 
       intent.putExtra("fromClass", this.getClass() + ""); 
       // intent.putExtra("mp3link", mp3link); 
       startActivity(intent); 
      } 
     }); 
     new AsyncTask<Void, Void, Void>() { 
      @Override 
      protected Void doInBackground(Void... params) { 

       XmlMapParser m = new XmlMapParser(Playlist.this, RECITER_ID); 
       HashMap<String, ArrayList<String>> map = m.convert(); 
       map.keySet(); 
       label = map.get("RecitorLabel").get(0); 
       title = map.get("Title").get(0); 
       url = map.get("Link").get(0); 
       back = (ImageView) findViewById(R.id.playlist_back); 
       back.setOnClickListener(new OnClickListener() { 

        @Override 
        public void onClick(View arg0) { 
         finish(); 
        } 
       }); 
       db.openDB(); 
       for (int i = 1; i < map.get("Link").size(); i++) { 
        if (db.isDownloaded(i, title, RECITER_ID)) { 
         songs.add(new Songs(i, map.get("Title").get(i), 
           Environment.getExternalStorageDirectory() 
             .getPath() 
             + "/" 
             + getString(R.string.app_name) 
             + "/" 
             + title 
             + "/" 
             + map.get("Title").get(i) 
             + ".mp3", title, true, RECITER_ID, 
           false)); 

        } else 
         songs.add(new Songs(i, map.get("Title").get(i), url 
           + label + "/" 
           + new DecimalFormat("000").format(i) + ".mp3", 
           title, false, RECITER_ID, false)); 
       } 
       db.closeDB(); 
       // Log.v("--",m.convert().get("Link").get(1)); 
       // [RecitorLabel, Title, Link] THIS ARE THE KEYS m 

       // Log.v("--", map.get("RecitorLabel").get(0)); 
       // Log.v("--", map.get("Link").get(1)); 
       return null; 
      } 

      protected void onPostExecute(Void result) { 
       adapter = new PlaylistAdapter(Playlist.this, songs); 
       list.setAdapter(adapter); 
       reciter.setText(songs.get(0).getRecitorName()); 
      }; 
     }.execute(); 

    } 

    @Override 
    public void onBackPressed() { 
     if (slidingMenu.isMenuShowing()) { 
      slidingMenu.toggle(); 
     } else { 
      super.onBackPressed(); 
     } 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     try { 
      if (Tplayer.getInstance().isPlaying()) { 
       adapter = new PlaylistAdapter(this, songs); 
       list.setAdapter(adapter); 
       adapter.notifyDataSetChanged(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_MENU) { 
      this.slidingMenu.toggle(); 
      return true; 
     } 
     return super.onKeyDown(keyCode, event); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case android.R.id.home: 
      this.slidingMenu.toggle(); 
      return true; 
     default: 
      return super.onOptionsItemSelected(item); 
     } 
    } 

    private void initWidgets() { 
     db = new DatabaseHelper(this); 
     manager = (Button) findViewById(R.id.playlist_download_manager); 
     manager.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Intent intent = new Intent(Playlist.this, DownloadManager.class); 
       startActivity(intent); 
      } 
     }); 
     reciter = (TextView) findViewById(R.id.playlist_reciter_name_top); 
     list = (ListView) findViewById(R.id.playlist_list); 
     downloadAll = (Button) findViewById(R.id.playlist_download_all); 
     manager = (Button) findViewById(R.id.playlist_download_manager); 
     songs = new ArrayList<Songs>(); 
     RECITER_ID = getIntent().getIntExtra("filename", -1); 
     // downloadAll.setOnClickListener(new OnClickListener() { 
     // 
     // @Override 
     // public void onClick(View v) { 
     // new DownloadAll(Playlist.this, songs); 
     // db.openDB(); 
     // for (int i = 0; i < songs.size(); i++) { 
     // db.addDownloaded(songs.get(i).getNumber(), songs.get(i) 
     // .getLink(), 0, songs.get(i).getRecitorID(), "", 
     // songs.get(i).getTitle()); 
     // } 
     // db.closeDB(); 
     // } 
     // }); 
     nowPlaying = (ImageView) findViewById(R.id.playlist_now_playing); 
     nowPlaying.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Tplayer tplayer = Tplayer.getInstance(); 
       if (tplayer.isPlaying()) { 
        Intent intent = new Intent(Playlist.this, PlayerFinal.class); 
        if (tplayer.isPlaying()) 
         intent.putExtra("songs", tplayer.getSongs()); 
        else 
         intent.putExtra("songs", songs); 
        if (tplayer.getSongs().size() == 14) 
         intent.putExtra("lang", 115); 
        intent.putExtra("position", tplayer.getPosition()); 
        startActivity(intent); 
       } 
      } 
     }); 
     // Jeremy Feinstein slidinglistadapter line 94 
     slidingMenu = new SlidingMenu(this); 
     slidingMenu.setMode(SlidingMenu.LEFT); 
     slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); 
     slidingMenu.setShadowWidthRes(R.dimen.slidingmenu_shadow_width); 
     slidingMenu.setShadowDrawable(R.drawable.slidingmenu_shadow); 
     slidingMenu.setBehindOffsetRes(R.dimen.slidingmenu_offset); 
     slidingMenu.setFadeDegree(0.35f); 
     slidingMenu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT); 
     slidingMenu.setMenu(R.layout.slidingmenu); 

    } 

} 

и мой плейлист адаптер Класс:

public class PlaylistAdapter extends BaseAdapter { 

    private Activity activity; 
    private static LayoutInflater inflater = null; 
    private ArrayList<Songs> data; 
    private DatabaseHelper db; 
    private SharedPreferences prefs; 
    int playpos; 
    int recitorID; 

    public PlaylistAdapter(Activity a, ArrayList<Songs> songs) { 
     activity = a; 
     data = songs; 
     db = new DatabaseHelper(a); 
     inflater = (LayoutInflater) activity 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     prefs = activity.getSharedPreferences("quantic.Quran", 
       Context.MODE_PRIVATE); 
     recitorID = prefs.getInt("recID", -1); 
     playpos = prefs.getInt("posPlaying", -1); 
    } 

    public int getCount() { 
     return data.size(); 
    } 

    public Object getItem(int position) { 
     return position; 
    } 

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

    public View getView(final int position, View convertView, 
      final ViewGroup parent) { 
     View vi = convertView; 
     if (convertView == null) 
      vi = inflater.inflate(R.layout.song_item, parent, false); 

     ImageView download = (ImageView) vi 
       .findViewById(R.id.playlist_item_download); 
     db.openDB(); 
     if (db.isDownloaded(data.get(position).getNumber(), data.get(position) 
       .getRecitorName(), data.get(position).getRecitorID())) 
      download.setImageResource(R.drawable.download_yes); 
     else { 
      download.setImageResource(R.drawable.download_no); 
      download.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 

        new DownloadFileFromURL(activity, data.get(position) 
          .getRecitorName(), data.get(position).getTitle(), 
          data.get(position).getLink(), data.get(position) 
            .getNumber(), data.get(position) 
            .getRecitorID()).execute(); 
        if (!db.isDBOpen()) 
         db.openDB(); 
        db.addDownloaded(data.get(position).getNumber(), 
          data.get(position).getLink(), 0, data.get(position) 
            .getRecitorID(), "", data.get(position) 
            .getTitle()); 

        Toast.makeText(activity, 
          "Downloading " + data.get(position).getTitle(), 
          Toast.LENGTH_SHORT).show(); 

       } 
      }); 
     } 
     db.closeDB(); 

     TextView number = (TextView) vi.findViewById(R.id.playlist_item_num); 
     TextView reciterName = (TextView) vi 
       .findViewById(R.id.playlist_item_reciterName); 
     reciterName.setText(data.get(position).getRecitorName()); 
     if (activity.getClass() == Playlist.class) { 
      reciterName.setVisibility(View.GONE); 
     } 
     TextView title = (TextView) vi.findViewById(R.id.playlist_item_reciter); 
     title.setText(data.get(position).getTitle()); 
     number.setText((position + 1) + ""); 
     ImageView eq = (ImageView) vi.findViewById(R.id.playlist_item_equlizer); 
     if (Tplayer.getInstance().isPlaying()) 
      if (Tplayer.getInstance().getPosition() == position 
        && data.get(position).getRecitorID() == Tplayer 
          .getInstance().getSong().getRecitorID()) { 
       eq.setVisibility(View.VISIBLE); 
       Ion.with(eq).load("http://darkodev.info/quran/dots.gif"); 
      } else { 
       eq.setVisibility(View.GONE); 
      } 

     return vi; 
    } 
} 

ответ

0

Очень старый вопрос, но ответа нет. Я уверен, что вы нашли исправление, но в любом случае.

Вы меняете объект списка композиций в фоновом режиме, и если Android решает перерисовать ваш список (пользователь прокручивает список), эффективно доступ к объекту списка композиций, он может измениться и вызвать это исключение.

Вам необходимо использовать список временных композиций и создать для него новый адаптер, чтобы обновить список, не изменяя текущий список адаптеров, пока не установите новый адаптер из основного потока пользовательского интерфейса.