我的Android应用程序存在很大问题。在应用程序中,我每隔30秒从JSON流获取数据以更新列表视图 - 如果有新数据,我只更新自定义适配器。如果我一次调用JSONParse / update任务,一切正常,但是当我把这个方法放在一个计时器任务中时,我的应用程序几乎没有运行,最终在10秒后关闭。如果有任何方法可以帮助我,我会非常感激。我很抱歉这里有很多代码。最重要的是,要注意callAsynchonousTask()方法。
这是完成大部分应用程序工作的类:
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;
}
}
}
}
答案 0 :(得分:1)
在UI线程上调用方法onPostExecute
,你正在做很多事情。尝试将代码保留在if(firstCall)
的{{1}}中,因为这是您需要访问UI的地方。上面的其余代码可以移动到onPostExecute
,这是在后台线程上调用的。
来自文档:
doInBackground(Params ...),在后台线程上调用 onPreExecute()完成后立即执行。
onPostExecute(Result),在后台后的UI线程上调用 计算完成。