我有一個包含兩個選項的菜單。其中一個選項用網頁內容刷新應用程序的內容。我想調暗屏幕上的ListView,然後顯示進度條,直到內容刷新。我有方法startLoadingAnimation()
和endLoadingAnimation()
完成此操作。但是當我在他們之間撥打refreshArticles()
時,他們停止工作。我在他們的打印語句顯示他們應該執行時,但是當Android - 使用AsyncTask調用方法會中斷其他方法
case R.id.refresh:
startLoadingAnimation();
refreshArticles();
endLoadingAnimation();
執行,只有打印語句通過,而不是UI更改。
全部活動代碼:
package com.bruno.newsreader;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.NumberPicker;
import android.widget.ProgressBar;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
public class ListActivity extends AppCompatActivity {
private ListView listView;
private int numArticles;
private SharedPreferences sharedPreferences;
private ArrayList<String> articleTitles;
private ArrayList<String> articleUrls;
private SQLiteDatabase articleDB;
private ProgressBar progressBar;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.options_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.refresh:
startLoadingAnimation();
refreshArticles();
endLoadingAnimation();
return true;
case R.id.numArticles:
final NumberPicker numberPicker = new NumberPicker(getApplicationContext());
numberPicker.setMaxValue(50);
numberPicker.setMinValue(5);
numberPicker.setValue(numArticles);
new AlertDialog.Builder(this)
.setTitle("Set Number of Articles")
.setMessage("This will determine how many articles are stored on your device:")
.setView(numberPicker)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
numArticles = numberPicker.getValue();
sharedPreferences.edit().putInt("numArticles", numArticles).apply();
}
})
.setNegativeButton("Cancel", null)
.show();
default:
return false;
}
}
public class TopArticleDownloadTask extends AsyncTask<URL, Void, JSONArray> {
@Override
protected JSONArray doInBackground(URL... urls) {
String jsonString = "";
URL url = urls[0];
HttpURLConnection urlConnection = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while(data != -1) {
char current = (char) data;
jsonString += current;
data = reader.read();
}
return new JSONArray(jsonString);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
public class IndividualArticleDownloadTask extends AsyncTask<URL, Void, JSONObject> {
@Override
protected JSONObject doInBackground(URL... urls) {
String jsonString = "";
URL url = urls[0];
HttpURLConnection urlConnection = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while(data != -1) {
char current = (char) data;
jsonString += current;
data = reader.read();
}
return new JSONObject(jsonString);
} catch (Exception e) {
}
return null;
}
}
private void refreshArticles() {
String topArticlesUrlString = "https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty";
URL topArticlesUrl = null;
try {
topArticlesUrl = new URL(topArticlesUrlString);
} catch (MalformedURLException e) {
e.printStackTrace();
}
TopArticleDownloadTask topArticleDownloadTask = new TopArticleDownloadTask();
JSONArray topArticlesJSON = null;
try {
topArticlesJSON = topArticleDownloadTask.execute(topArticlesUrl).get();
} catch (Exception e) {
e.printStackTrace();
}
int[] articleIds = new int[numArticles];
for (int i = 0; i < articleIds.length; i++) {
try {
articleIds[i] = topArticlesJSON.getInt(i);
} catch (JSONException e) {
e.printStackTrace();
}
}
String articleUrlStart = " https://hacker-news.firebaseio.com/v0/item/";
String articleUrlEnd = ".json?print=pretty";
articleDB.execSQL("DELETE FROM articles");
for (int id : articleIds) {
String articleUrlString = articleUrlStart + id + articleUrlEnd;
URL articleUrl = null;
try {
articleUrl = new URL(articleUrlString);
} catch (MalformedURLException e) {
e.printStackTrace();
}
JSONObject articleJSON = null;
try {
IndividualArticleDownloadTask individualArticleDownloadTask = new IndividualArticleDownloadTask();
articleJSON = individualArticleDownloadTask.execute(articleUrl).get();
} catch (Exception e) {
e.printStackTrace();
}
try {
String title = articleJSON.getString("title");
title = title.replaceAll("'", "''");
String url = articleJSON.getString("url");
articleDB.execSQL("INSERT INTO articles (title, url) VALUES ('" + title + "', '" + url + "')");
} catch (Exception e) {
e.printStackTrace();
}
}
syncArrayListsWithDB();
}
private void syncArrayListsWithDB() {
articleTitles.clear();
articleUrls.clear();
Cursor cursor = articleDB.rawQuery("SELECT * FROM articles", null);
if (cursor.moveToFirst()) {
while(!cursor.isAfterLast()) {
String title = cursor.getString(0);
String url = cursor.getString(1);
articleTitles.add(title);
articleUrls.add(url);
cursor.moveToNext();
}
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, articleTitles);
listView.setAdapter(arrayAdapter);
}
private void startLoadingAnimation() {
System.out.println("start start load");
listView.setAlpha(.25f);
progressBar.setVisibility(View.VISIBLE);
System.out.println("end start load");
}
private void endLoadingAnimation() {
System.out.println("start end load");
listView.setAlpha(1);
progressBar.setVisibility(View.INVISIBLE);
System.out.println("end end load");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
articleTitles = new ArrayList<>();
articleUrls = new ArrayList<>();
listView = (ListView) findViewById(R.id.listView);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
sharedPreferences = this.getSharedPreferences("com.bruno.newsreader", Context.MODE_PRIVATE);
numArticles = sharedPreferences.getInt("numArticles", 10);
articleDB = this.openOrCreateDatabase("Data", MODE_PRIVATE, null);
articleDB.execSQL("CREATE TABLE IF NOT EXISTS articles (title VARCHAR, url VARCHAR)");
Cursor c = articleDB.rawQuery("SELECT count(*) FROM articles", null);
c.moveToFirst();
int count = c.getInt(0);
if (count == 0) {
refreshArticles();
} else {
syncArrayListsWithDB();
}
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getApplicationContext(), ReaderActivity.class);
intent.putExtra("url", articleUrls.get(position));
startActivity(intent);
}
});
}
}
謝謝!我將我的工作移到了一個新的'AsyncTask',它在'onPreExecute()'和'onPostExecute(Result result)'方法中調用了兩個動畫方法。現在起作用了。 –