2015-06-17 48 views
0

我有我的android应用程序的巨大问题。在应用程序中,我每隔30秒从JSON流获取数据以更新列表视图 - 如果有新数据,我只更新自定义适配器。如果我调用JSONParse/update任务一次,一切正常,但是当我将这个方法放入一个计时器任务中时,我的应用程序几乎没有运行,最终在10秒后关闭。如果有什么办法可以帮助我,我将不胜感激。我真的很抱歉,这里有太多的代码。最重要的是,注意调用AsynchonousTask()方法。应用程序在其主线程上做了太多工作?

这里是大多数应用程序的工作正在做的类:

public class LiveStreamFragment extends Fragment{ 

public WXYCMediaPlayer mediaPlayer; 

ListView list; 
TextView song; 
TextView artist; 

public ArrayList<HashMap<String, String>> oslist = new ArrayList<HashMap<String, String>>(); 

private static String wxycUrl = "http://www.wxyc.info/playlists/recentEntries?v=2"; 
private static String streamURL = "http://152.2.204.90:8000/wxyc.mp3"; 

private static final String TAG_PLAYCUTS = "playcuts"; 
private static final String TAG_SONG = "songTitle"; 
private static final String TAG_ARTIST = "artistName"; 
private static final String TAG_ALBUM = "releaseTitle"; 
private static final String TAG_TALKSETS = "talksets"; 
private static final String TAG_CHRONID = "chronOrderID"; 
private static final String TAG_BREAKPOINTS = "breakpoints"; 
private static final String TAG_HOUR = "hour"; 
private static final String TAG_LAYOUT = "layoutType"; 

private SwipeRefreshLayout swipeLayout; 
private Button update_button; 

private JSONArray playcuts = null; 
private JSONArray talksets = null; 
private JSONArray breakpoints = null; 

private Playcut[] playcutArr; 
private Talkset[] talksetArr; 
private Breakpoint[] breakpointArr; 

public View rootView; 

boolean firstCall = true; 
boolean buttonActivated; 

LiveAdapter adapter; 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    rootView = inflater.inflate(R.layout.stream_fragment, container, false); 

    list = (ListView) rootView.findViewById(R.id.list); 
    adapter = new LiveAdapter(LiveStreamFragment.this.getActivity(), oslist, LiveStreamFragment.this, list); 
    list.setAdapter(adapter); 

    buttonActivated = false; 

    new JSONParse().execute(); 
    this.callAsynchronousTask(); 

    update_button = (Button) rootView.findViewById(R.id.update_button); 
    update_button.setText("New Tracks!"); 
    update_button.setGravity(Gravity.CENTER_HORIZONTAL); 
    update_button.setVisibility(View.GONE); 
    update_button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      adapter.updateDataList(oslist); 
      update_button.setVisibility(View.GONE); 
      buttonActivated = false; 
     } 
    }); 

    list.setOnScrollListener(new AbsListView.OnScrollListener() { 
     @Override 
     public void onScrollStateChanged(AbsListView view, int scrollState) { 
      if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) { 
       if(buttonActivated) { 
        update_button.setVisibility(View.VISIBLE); 
       } 
      } 
     } 

     @Override 
     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
       if(buttonActivated) { 
        update_button.setVisibility(View.GONE); 
       } 
     } 
    }); 

    return rootView; 
} 

public void addHeartData(HashMap<String, String> heartMap){ 
    Bus bus = new Bus(); 
    BusProvider.getInstance().post(heartMap); 
} 

/******** Calling the JSON Feed to update every 30 seconds ********/ 
public void callAsynchronousTask() { 
    final Handler handler = new Handler(); 
    Timer timer = new Timer(); 
    TimerTask doAsynchronousTask = new TimerTask() { 
     @Override 
     public void run() { 
      handler.post(new Runnable() { 
       public void run() { 
        try { 
         new JSONParse().execute(); 

        } catch (Exception e) { 
         // TODO Auto-generated catch block 
        } 
       } 
      }); 
     } 
    }; 
    timer.schedule(doAsynchronousTask, 0, 30000); //execute in every 50000 ms 
} 

/******** JSON Parsing and sorting class ********/ 
public class JSONParse extends AsyncTask<String, String, JSONObject> { 
    private ProgressDialog pDialog; 

    private String chronIDCheck; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 

     oslist = new ArrayList<HashMap<String, String>>(); 

     /*DELAY THIS TASK FOR THE SPLASH SCREEN TIME*/ 
     //mediaPlayer = new WXYCMediaPlayer(streamURL, this.getActivity()); 

     //HashMap<String, String> streamMap = new HashMap<String, String>(); //Add this to the media player method. 
     //streamMap.put(TAG_LAYOUT, "LiveStream"); 
     //oslist.add(streamMap); 

     /*list = (ListView) rootView.findViewById(R.id.list); 
     adapter = new LiveAdapter(LiveStreamFragment.this.getActivity(), oslist, LiveStreamFragment.this, list); 
     list.setAdapter(adapter);*/ 
    } 

    @Override 
    protected JSONObject doInBackground(String... args) { 
     JSONParser jParser = new JSONParser(); 
     // Getting JSON from URL 
     JSONObject json = jParser.getJSONFromUrl(wxycUrl); 

     return json; 
    } 

    @Override 
    protected void onPostExecute(JSONObject json) { 
     try { 

      playcuts = json.getJSONArray(TAG_PLAYCUTS); 
      talksets = json.getJSONArray(TAG_TALKSETS); 
      breakpoints = json.getJSONArray(TAG_BREAKPOINTS); 

      playcutArr = new Playcut[playcuts.length()]; 
      talksetArr = new Talkset[talksets.length()]; 
      breakpointArr = new Breakpoint[breakpoints.length()]; 

      for(int i = 0; i < playcuts.length(); i++){ 
       JSONObject playcut = playcuts.getJSONObject(i); 

       playcutArr[i] = new Playcut(
         playcut.getString(TAG_SONG), 
         playcut.getString(TAG_ARTIST), 
         playcut.getString(TAG_ALBUM), 
         playcut.getInt(TAG_CHRONID)); 
      } 

      for(int j = 0; j < talksets.length(); j++){ 
       JSONObject talkset = talksets.getJSONObject(j); 

       talksetArr[j] = new Talkset(
         talkset.getInt(TAG_CHRONID)); 

      } 

      for(int k = 0; k < breakpoints.length(); k++){ 
       JSONObject breakpoint = breakpoints.getJSONObject(k); 

       breakpointArr[k] = new Breakpoint(
         breakpoint.getInt(TAG_CHRONID), 
         breakpoint.getLong(TAG_HOUR) 
       ); 
      } 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

     int playcutIndex = 0; 
     int talksetIndex = 0; 
     int breakpointIndex = 0; 
     int minID; 
     int i = 0; 

     /******** Algorithm to consolidate playcuts, breakpoints, and talksets into one arraylist by their chronological ID ********/ 

     while(i < 30){ 

      HashMap<String, String> map = new HashMap<String, String>(); 

      minID = Math.max(
        playcutArr[playcutIndex].chronID, (int) Math.max(
          talksetArr[talksetIndex].chronID, breakpointArr[breakpointIndex].chronID 
        ) 
      ); 

      if(minID == playcutArr[playcutIndex].chronID) { 

       map.put(TAG_SONG, playcutArr[playcutIndex].song); 
       map.put(TAG_ARTIST, playcutArr[playcutIndex].artist); 
       map.put(TAG_ALBUM, playcutArr[playcutIndex].album); 
       map.put(TAG_LAYOUT, "Playcut"); 
       map.put(TAG_CHRONID,""+playcutArr[playcutIndex].chronID); 

       StringBuilder stringBuilder = new StringBuilder("http://ws.audioscrobbler.com/2.0/"); 
       stringBuilder.append("?method=album.getinfo"); 
       stringBuilder.append("&api_key="); 
       stringBuilder.append("2ead17554acf667f27cf7dfd4c368f15"); 
       String albumURL = null; 

       try { 
        stringBuilder.append("&artist=" + URLEncoder.encode(map.get(TAG_ARTIST), "UTF-8")); 
        stringBuilder.append("&album=" + URLEncoder.encode(map.get(TAG_ALBUM), "UTF-8")); 
        albumURL = new RetrieveAlbumArtUrlTask().execute(stringBuilder.toString()).get(); 

       } catch (UnsupportedEncodingException e) { 
        albumURL = null; 
       } catch (InterruptedException e) { 
        albumURL = null; 
       } catch (ExecutionException e) { 
        albumURL = null; 
       } catch (IllegalArgumentException e) { 
        albumURL = null; 
       } 

       map.put("albumArtUrl", albumURL); 

       playcutIndex = playcutIndex + 1; 
      } 

      if(minID == talksetArr[talksetIndex].chronID) { 

       map.put(TAG_SONG, "Talkset"); 
       map.put(TAG_ARTIST, null); 
       map.put(TAG_LAYOUT, "Talkset"); 
       map.put(TAG_CHRONID,""+talksetArr[talksetIndex].chronID); 



       talksetIndex = talksetIndex + 1; 
      } 

      if(minID == breakpointArr[breakpointIndex].chronID) { 

       map.put(TAG_SONG, "Breakpoint"); 
       map.put(TAG_ARTIST, null); 
       map.put(TAG_LAYOUT, "Breakpoint"); 
       map.put(TAG_HOUR, ""+breakpointArr[breakpointIndex].hour);   
        map.put(TAG_CHRONID,""+breakpointArr[breakpointIndex].chronID); 

       breakpointIndex = breakpointIndex + 1; 
      } 

      map.put("Clicked", "False"); 



      oslist.add(map); 

      chronIDCheck = oslist.get(0).get(TAG_CHRONID); 
      i++; 

     } 

     /* If this is the first JSON Parse, we instantiate the adapter, otherwise we just update */ 
     if(firstCall) { 

      list = (ListView) rootView.findViewById(R.id.list); 
      adapter = new LiveAdapter(LiveStreamFragment.this.getActivity(), oslist, LiveStreamFragment.this, list); 
      list.setAdapter(adapter); 

      firstCall = false; 

     } else { 

      if(!adapter.chronIdCheck().equals(oslist.get(0).get(TAG_CHRONID))) { 
       //adapter.updateDataList(oslist); 
       update_button.setVisibility(View.VISIBLE); 
       buttonActivated = true; 

      } 

     } 
    } 

} 

} 

这是我的新doInBackground()代码:

@Override 
    protected Void doInBackground(String... args) { 
     jParser = new JSONParser(); 
     json = jParser.getJSONFromUrl(wxycUrl); 
     Log.v("TEST","BACKGROUND"); 

     try { 

      playcuts = json.getJSONArray(TAG_PLAYCUTS); 
      talksets = json.getJSONArray(TAG_TALKSETS); 
      breakpoints = json.getJSONArray(TAG_BREAKPOINTS); 

      playcutArr = new Playcut[playcuts.length()]; 
      talksetArr = new Talkset[talksets.length()]; 
      breakpointArr = new Breakpoint[breakpoints.length()]; 

      for(int i = 0; i < playcuts.length(); i++){ 
       JSONObject playcut = playcuts.getJSONObject(i); 

       playcutArr[i] = new Playcut(
         playcut.getString(TAG_SONG), 
         playcut.getString(TAG_ARTIST), 
         playcut.getString(TAG_ALBUM), 
         playcut.getInt(TAG_CHRONID)); 
      } 

      for(int j = 0; j < talksets.length(); j++){ 
       JSONObject talkset = talksets.getJSONObject(j); 

       talksetArr[j] = new Talkset(
         talkset.getInt(TAG_CHRONID)); 

      } 

      for(int k = 0; k < breakpoints.length(); k++){ 
       JSONObject breakpoint = breakpoints.getJSONObject(k); 

       breakpointArr[k] = new Breakpoint(
         breakpoint.getInt(TAG_CHRONID), 
         breakpoint.getLong(TAG_HOUR) 
       ); 
      } 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 



     int playcutIndex = 0; 
     int talksetIndex = 0; 
     int breakpointIndex = 0; 
     int minID; 
     int i = 0; 

     /******** Algorithm to consolidate playcuts, breakpoints, and talksets into one arraylist by their chronological ID ********/ 

     while(i < 30){ 

      HashMap<String, String> map = new HashMap<String, String>(); 

      minID = Math.max(
        playcutArr[playcutIndex].chronID, (int) Math.max(
          talksetArr[talksetIndex].chronID, breakpointArr[breakpointIndex].chronID 
        ) 
      ); 

      if(minID == playcutArr[playcutIndex].chronID) { 

       map.put(TAG_SONG, playcutArr[playcutIndex].song); 
       map.put(TAG_ARTIST, playcutArr[playcutIndex].artist); 
       map.put(TAG_ALBUM, playcutArr[playcutIndex].album); 
       map.put(TAG_LAYOUT, "Playcut"); 
       map.put(TAG_CHRONID,""+playcutArr[playcutIndex].chronID); 

       StringBuilder stringBuilder = new StringBuilder("http://ws.audioscrobbler.com/2.0/"); 
       stringBuilder.append("?method=album.getinfo"); 
       stringBuilder.append("&api_key="); 
       stringBuilder.append("2ead17554acf667f27cf7dfd4c368f15"); 
       String albumURL = null; 

       try { 
        stringBuilder.append("&artist=" + URLEncoder.encode(map.get(TAG_ARTIST), "UTF-8")); 
        stringBuilder.append("&album=" + URLEncoder.encode(map.get(TAG_ALBUM), "UTF-8")); 
        albumURL = new RetrieveAlbumArtUrlTask().execute(stringBuilder.toString()).get(); 

       } catch (UnsupportedEncodingException e) { 
        albumURL = null; 
       } catch (InterruptedException e) { 
        albumURL = null; 
       } catch (ExecutionException e) { 
        albumURL = null; 
       } catch (IllegalArgumentException e) { 
        albumURL = null; 
       } 

       map.put("albumArtUrl", albumURL); 

       playcutIndex = playcutIndex + 1; 
      } 

      if(minID == talksetArr[talksetIndex].chronID) { 

       map.put(TAG_SONG, "Talkset"); 
       map.put(TAG_ARTIST, null); 
       map.put(TAG_LAYOUT, "Talkset"); 
       map.put(TAG_CHRONID,""+talksetArr[talksetIndex].chronID); 



       talksetIndex = talksetIndex + 1; 
      } 

      if(minID == breakpointArr[breakpointIndex].chronID) { 

       map.put(TAG_SONG, "Breakpoint"); 
       map.put(TAG_ARTIST, null); 
       map.put(TAG_LAYOUT, "Breakpoint"); 
       map.put(TAG_HOUR, ""+breakpointArr[breakpointIndex].hour); 
       map.put(TAG_CHRONID,""+breakpointArr[breakpointIndex].chronID); 

       breakpointIndex = breakpointIndex + 1; 
      } 

      map.put("Clicked", "False"); 

      oslist.add(map); 

      chronIDCheck = oslist.get(0).get(TAG_CHRONID); 
      i++; 

     } 

     Log.v("Test", "Background 2"); 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void args) { 
     Log.v("TEST","POST"); 

    /* If this is the first JSON Parse, we instantiate the adapter, otherwise we just update */ 
     if(firstCall) { 

      list = (ListView) rootView.findViewById(R.id.list); 
      adapter = new LiveAdapter(LiveStreamFragment.this.getActivity(), oslist, LiveStreamFragment.this, list); 
      list.setAdapter(adapter); 

      firstCall = false; 

     } else { 

      if(!adapter.chronIdCheck().equals(oslist.get(0).get(TAG_CHRONID))) { 
       //adapter.updateDataList(oslist); 
       update_button.setVisibility(View.VISIBLE); 
       buttonActivated = true; 

      } 

     } 

    } 

} 
+3

尝试将大量的json解析内容移植到AsyncTask的doInBackground方法中。 onPostExecute方法应该只用于更新您的用户界面 – mray190

回答

1

方法onPostExecute被称为UI线程上,而你正在做很多事情。请尝试将代码从if(firstCall)保存在onPostExecute中,因为那是您需要访问UI的地方。上面的代码的其余部分可以移动到doInBackground,后者在后台线程上调用。

从文档:

doInBackground(参数...),onPreExecute后,立即在后台线程 ()调用执行完毕。

onPostExecute(Result),在计算完成后在UI线程上调用。

+0

我试过这样做,但现在它说onPostExecute从未使用?为什么是这样? –

+1

您是否记得更改AsyncTask的签名?现在它可能应该是AsyncTask ,onPostExecute应该没有参数,doInBackground不应该返回任何东西。 – 2Dee

+1

基本上,AsyncTask的签名反映了使用的对象。你曾经把String作为参数类型,并返回一个JsonObject,但是如果你在doInBackground中没有返回任何东西,你的AsyncTask定义/签名需要相应地改变。 – 2Dee

相关问题