我遇到了显示网站实时内容的任务问题。
我一直在玩这段代码并玩弄状态,但我似乎无法让它正常工作。
到目前为止,我能够提出的唯一解决方案是完全禁用方向更改,但如果可能的话,我宁愿不这样做。
这是堆栈跟踪:
STACK_TRACE = java.lang.IllegalArgumentException:视图未附加到窗口管理器 在android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:653) 在android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:349) 在android.view.WindowManagerImpl $ CompatModeWrapper.removeView(WindowManagerImpl.java:160) 在android.app.Dialog.dismissDialog(Dialog.java:319) 在android.app.Dialog.dismiss(Dialog.java:302) 在cl.cromer.tronwell.concepcion.Progress.dismiss(Progress.java:72) at cl.cromer.tronwell.concepcion.AdditionalMaterial.databaseLoaded(AdditionalMaterial.java:149) at cl.cromer.tronwell.concepcion.AdditionalMaterial.access $ 13(AdditionalMaterial.java:122) at cl.cromer.tronwell.concepcion.AdditionalMaterial $ 1 $ 1.run(AdditionalMaterial.java:73) 在android.os.Handler.handleCallback(Handler.java:615) 在android.os.Handler.dispatchMessage(Handler.java:92) 在android.os.Looper.loop(Looper.java:137) 在android.app.ActivityThread.main(ActivityThread.java:5031) at java.lang.reflect.Method.invokeNative(Native Method) 在java.lang.reflect.Method.invoke(Method.java:511) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:792) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555) 在dalvik.system.NativeStart.main(本地方法)
以下是我崩溃的类的代码:
package cl.cromer.tronwell.concepcion;
import java.util.Calendar;
import java.util.HashMap;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.ContentValues;
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.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import cl.cromer.tronwell.concepcion.DBSchema.DBAdditionalMaterial;
import cl.cromer.tronwell.concepcion.DBSchema.DBAdditionalMaterialGroups;
import cl.cromer.tronwell.concepcion.Files.Download;
public class AdditionalMaterial extends ActionBarActivity implements ListenerXML, ListenerDownload, ListenerAsync {
private final static String URL = "action=downloads";
private XMLParser xmlParser;
private Progress progress = null;
// Parsers
private SQLParser sqlParser;
private Handler threadHandler = new Handler();
// The database
private SQLiteDatabase tronDB;
private int downloadId = 0;
private boolean downloadAll = false;
private int downloadCount = 1;
private int firstDownloadAvailable = 0;
private String fileName;
private Files files = new Files();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("debug", "onCreate");
setContentView(R.layout.activity_additional_material);
//progress = new Progress();
//progress.show(this, this, false);
sqlParser = new SQLParser(this);
new Thread(new Runnable() {
public void run() {
tronDB = sqlParser.getWritableDatabase();
threadHandler.post(new Runnable() {
public void run() {
databaseLoaded();
}
});
}
}).start();
}
@Override
protected void onStart() {
super.onStart();
Log.d("debug", "onStart");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d("debug", "onRestart");
}
@Override
protected void onResume() {
super.onResume();
progress = new Progress();
progress.show(this, this, false);
Log.d("debug", "onResume");
}
@Override
protected void onStop() {
super.onStop();
Log.d("debug", "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
progress = null;
Log.d("debug", "onDestroy");
}
@Override
public void onPause() {
super.onPause();
Log.d("debug", "onDestroy");
}
private void databaseLoaded() {
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
long materialDate = settings.getLong(Settings.MATERIAL_DATE, Settings.MATERIAL_DATE_DEFAULT);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
long currentDate = calendar.getTimeInMillis();
if (currentDate > materialDate ) {
// Update the database
String rut = settings.getString(Settings.RUT, Settings.RUT_DEFAULT);
String password = settings.getString(Settings.PASSWORD, Settings.PASSWORD_DEFAULT);
HashMap<String, String> postData = new HashMap<String, String>();
postData.put("rut", rut);
postData.put("pass", password);
xmlParser = new XMLParser(this, postData);
xmlParser.fetchListener = this; // Tell the XMLParser that this activity has the listener
xmlParser.execute(MainActivity.URL + URL);
}
else {
// Material does not need to be updated, just show what is in the database
if (progress != null && progress.isShowing()) {
progress.dismiss();
}
ShowContent showContent = new ShowContent(this);
showContent.asyncListener = this; // Tell the task that this class is listening
showContent.execute();
}
}
private void fetchFinished(HashMap<String, HashMap<String, String>> xmlData) {
// Let's put the groups in the database
HashMap<String, String> xmlHash = xmlData.get("1");
String groups = xmlHash.get("groups");
for (int i = 1; i <= Integer.valueOf(groups); i++) {
ContentValues values = new ContentValues();
values.put(DBAdditionalMaterialGroups.COLUMN_ID, String.valueOf(i));
values.put(DBAdditionalMaterialGroups.COLUMN_NAME, xmlHash.get("group" + String.valueOf(i)));
tronDB.replace(
DBAdditionalMaterialGroups.TABLE_NAME,
null,
values);
}
// Now the material
for (int i = 2; i <= xmlData.size() - 1; i++) {
xmlHash = xmlData.get(String.valueOf(i));
ContentValues values = new ContentValues();
values.put(DBAdditionalMaterial.COLUMN_ID, xmlHash.get("id"));
values.put(DBAdditionalMaterial.COLUMN_NAME, xmlHash.get("title"));
values.put(DBAdditionalMaterial.COLUMN_GROUP, xmlHash.get("group"));
values.put(DBAdditionalMaterial.COLUMN_TYPE, xmlHash.get("type"));
values.put(DBAdditionalMaterial.COLUMN_URL1, xmlHash.get("url1"));
values.put(DBAdditionalMaterial.COLUMN_URL2, xmlHash.get("url2"));
tronDB.replace(
DBAdditionalMaterial.TABLE_NAME,
null,
values);
}
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
SharedPreferences.Editor settingsEditor = settings.edit();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
long currentDate = calendar.getTimeInMillis();
settingsEditor.putLong(Settings.MATERIAL_DATE, currentDate);
settingsEditor.commit();
progress.dismiss();
ShowContent showContent = new ShowContent(this);
showContent.asyncListener = this; // Tell the task that this class is listening
showContent.execute();
}
@TargetApi(Build.VERSION_CODES.FROYO)
protected class ShowContent extends AsyncTask<String, View, Void> {
private Context context;
private PowerManager.WakeLock wakeLock;
protected ListenerAsync asyncListener = null; // This needs to be set from the parent activity
private LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linear_layout);
protected ShowContent(Context context) {
this.context = context;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// Let's make sure the CPU doesn't go to sleep
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
wakeLock.acquire();
}
@SuppressLint("InflateParams")
@Override
protected Void doInBackground(String... passedInfo) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View categoryView;
View downloadView;
View seperatorView;
TextView textView = new TextView(context);
ImageButton imageButton = new ImageButton(context);
Cursor cursorMaterialGroups = tronDB.query(
DBAdditionalMaterialGroups.TABLE_NAME,
DBAdditionalMaterialGroups.ALL_COLUMNS,
null,
null,
null,
null,
DBAdditionalMaterialGroups.COLUMN_ID + " ASC",
null);
while (cursorMaterialGroups.moveToNext()) {
// Create a group TextView by inflating a layout
categoryView = inflater.inflate(R.layout.additional_material_category, null);
textView = (TextView) categoryView;
textView.setText(cursorMaterialGroups.getString(cursorMaterialGroups.getColumnIndex(DBAdditionalMaterialGroups.COLUMN_NAME)));
publishProgress(textView);
// Now to get the downloads from the group
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_GROUP + "=" + cursorMaterialGroups.getString(cursorMaterialGroups.getColumnIndex(DBAdditionalMaterialGroups.COLUMN_ID)),
null,
null,
null,
DBAdditionalMaterial.COLUMN_ID + " ASC",
null);
downloadCount += cursorMaterial.getCount();
while (cursorMaterial.moveToNext()) {
downloadView = inflater.inflate(R.layout.additional_material_download, null);
// Download title
textView = (TextView) downloadView.findViewById(R.id.download_title);
textView.setText(cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_NAME)));
// Download/play button
imageButton = (ImageButton) downloadView.findViewById(R.id.download_button);
imageButton.setId(Integer.valueOf(cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_ID))));
String fileName = null;
if (cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE)).equals("pdf")) {
fileName = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_ID)) + ".pdf";
}
else {
fileName = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_ID)) + ".mp3";
}
Drawable drawable = getResources().getDrawable(R.drawable.ic_action_play);
if (!files.fileExists(context, fileName)) {
if (firstDownloadAvailable == 0) {
firstDownloadAvailable = imageButton.getId();
}
drawable = getResources().getDrawable(R.drawable.ic_action_save);
imageButton.setImageDrawable(drawable);
imageButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
downloadId = view.getId();
download();
}
});
}
else {
imageButton.setImageDrawable(drawable);
imageButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String contentId = String.valueOf(view.getId());
openContent(contentId);
}
});
}
publishProgress(downloadView);
if (!cursorMaterial.isLast()) {
seperatorView = inflater.inflate(R.layout.additional_material_seperator, null);
publishProgress(seperatorView);
}
}
cursorMaterial.close();
}
// Other
categoryView = inflater.inflate(R.layout.additional_material_category, null);
textView = (TextView) categoryView;
textView.setText("OTHER");
publishProgress(textView);
// Download all
downloadView = inflater.inflate(R.layout.additional_material_download, null);
// Download title
textView = (TextView) downloadView.findViewById(R.id.download_title);
textView.setText("Download all material");
// Download/play button
imageButton = (ImageButton) downloadView.findViewById(R.id.download_button);
imageButton.setId(1);
Drawable drawable = getResources().getDrawable(R.drawable.ic_action_play);
drawable = getResources().getDrawable(R.drawable.ic_action_save);
imageButton.setImageDrawable(drawable);
imageButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
downloadId = firstDownloadAvailable;
downloadAll = true;
download();
}
});
publishProgress(downloadView);
cursorMaterialGroups.close();
return null;
}
@Override
protected void onProgressUpdate(View... view) {
linearLayout.addView(view[0]);
}
@Override
protected void onPostExecute(Void result) {
wakeLock.release();
if (asyncListener != null) {
// Call the listener if one is set
asyncListener.onAsyncComplete();
}
}
}
private void download() {
progress.show(this, this, true);
Files files = new Files();
// Check if the memory card can be written to
if (files.isWriteable()) {
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_ID + "=" + String.valueOf(downloadId),
null,
null,
null,
null,
"1");
cursorMaterial.moveToFirst();
String title = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_NAME));
String type = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE));
String url1 = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_URL1));
String url2 = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_URL2));
cursorMaterial.close();
if (type.equals("pdf")) {
fileName = String.valueOf(downloadId) + ".pdf";
}
else {
fileName = String.valueOf(downloadId) + ".mp3";
}
// Change the message in the downloading prompt
progress.setMessage(getString(R.string.general_downloading) + " " + title);
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
String rut = settings.getString(Settings.RUT, Settings.RUT_DEFAULT);
String url = url1 + rut + url2;
url = url.replace(" ", "%20");
final Download download = files.new Download(this, fileName, progress);
download.downloadListener = this;
download.execute(url);
progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
downloadAll = false;
download.cancel(true);
}
});
}
else {
progress.dismiss();
Toast.makeText(this, getString(R.string.general_no_memory), Toast.LENGTH_SHORT).show();
}
}
private void openContent(String contentId) {
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_ID + "=" + contentId,
null,
null,
null,
null,
"1");
cursorMaterial.moveToFirst();
String type = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE));
cursorMaterial.close();
String fileName = "";
String mimeType = "";
if (type.equals("pdf")) {
fileName = contentId + ".pdf";
mimeType = "application/pdf";
}
else {
fileName = contentId + ".mp3";
mimeType = "audio/mp3";
}
files.openFile(this, fileName, mimeType);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (intent.getBooleanExtra(ConnectionFailed.RETRY, false)) {
// Failed, let's try the connection again
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
String rut = settings.getString(Settings.RUT, Settings.RUT_DEFAULT);
String password = settings.getString(Settings.PASSWORD, Settings.PASSWORD_DEFAULT);
HashMap<String, String> postData = new HashMap<String, String>();
postData.put("rut", rut);
postData.put("pass", password);
xmlParser = new XMLParser(this, postData);
xmlParser.fetchListener = this; // Tell the XMLParser that this activity has the listener
xmlParser.execute(MainActivity.URL + URL);
}
}
// This is the listener for the xml
public void onFetchComplete(String xml) {
if (xml == null) {
progress.dismiss();
// Failed to fetch xml, either a server error or an internet connection problem
Intent intent = new Intent(this, ConnectionFailed.class);
startActivityForResult(intent, 1);
}
else {
HashMap<String, HashMap<String, String>> xmlHash = xmlParser.parseXML(xml);
new User().checkUserValidation(xmlHash.get("0"));
fetchFinished(xmlHash);
}
}
// This is the listener for the download
public void onDownloadComplete(boolean result) {
progress.dismiss();
if (!result) {
Toast.makeText(this, getString(R.string.general_failed_download), Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(this, getString(R.string.general_download_complete), Toast.LENGTH_SHORT).show();
Drawable drawable = getResources().getDrawable(R.drawable.ic_action_play);
ImageButton buttonView = (ImageButton) findViewById(downloadId);
buttonView.setImageDrawable(drawable);
buttonView.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String contentId = String.valueOf(view.getId());
openContent(contentId);
}
});
if (downloadAll) {
while (downloadCount >= downloadId) {
downloadId++;
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_ID + "=" + String.valueOf(downloadId),
null,
null,
null,
null,
"1");
cursorMaterial.moveToFirst();
String type = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE));
cursorMaterial.close();
if (type.equals("pdf")) {
fileName = String.valueOf(downloadId) + ".pdf";
}
else {
fileName = String.valueOf(downloadId) + ".mp3";
}
if (!files.fileExists(this, fileName)) {
download();
break;
}
}
if (downloadCount == downloadId) {
// The last one downloaded we can now stop the process
downloadAll = false;
}
}
}
}
// This is the listener for the Async
public void onAsyncComplete() {
progress.dismiss();
}
}
以下是我的进度条的代码:
package cl.cromer.tronwell.concepcion;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
public final class Progress {
protected ProgressDialog progressBar = null;
private int oldOrientation = -1; // Orientation not set
private Activity activity;
protected void show(Context context, Activity activity, boolean cancelable) {
this.activity = activity;
// Disable rotation while we are loading something
oldOrientation = activity.getRequestedOrientation();
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
if (progressBar != null && progressBar.isShowing()) {
activity.setRequestedOrientation(oldOrientation);
progressBar.dismiss();
}
progressBar = new ProgressDialog(context);
progressBar.setCancelable(cancelable);
if (!cancelable) {
progressBar.setMessage(context.getString(R.string.general_loading));
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
}
else {
progressBar.setIndeterminate(true);
progressBar.setCanceledOnTouchOutside(false);
progressBar.setMessage(context.getString(R.string.general_downloading));
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
}
progressBar.setProgress(0);
progressBar.setMax(100);
progressBar.show();
}
protected void setMessage(String message) {
progressBar.setMessage(message);
}
protected void setIndeterminate(boolean indeterminate) {
progressBar.setIndeterminate(indeterminate);
}
protected void setProgress(int progress) {
progressBar.setProgress(progress);
}
protected void setOnCancelListener(DialogInterface.OnCancelListener listener) {
progressBar.setOnCancelListener(listener);
}
protected boolean isShowing() {
if (progressBar.isShowing()) {
return true;
}
return false;
}
protected void dismiss() {
// Turn rotation back to it's previous state
activity.setRequestedOrientation(oldOrientation);
if (progressBar != null && progressBar.isShowing()) {
progressBar.dismiss();
}
}
}