泄露了Windows ProgressDialog Android Dropbox
我正试图通过AsyncTask将文件上载到dropbox,但发现窗口泄漏错误:泄露了Windows ProgressDialog Android Dropbox,android,progressdialog,dropbox-api,Android,Progressdialog,Dropbox Api,我正试图通过AsyncTask将文件上载到dropbox,但发现窗口泄漏错误: 05-16 16:05:53.523: E/WindowManager(4528): Activity com.example.wecharades.ShowVideo has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@2be59ea8 that was originally added here 我查看并理解这是因为我
05-16 16:05:53.523: E/WindowManager(4528): Activity com.example.wecharades.ShowVideo has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@2be59ea8 that was originally added here
我查看并理解这是因为我的活动已退出,而progressdialog仍在那里。我不明白为什么我的活动会退出。它只是一个屏幕,有一个按钮可以用来上传文件。我使用几乎相同的代码从dropbox下载一个文件,它工作得非常完美
有什么建议吗?
提前谢谢
public class UploadFile extends AsyncTask<Void, Long, Boolean> {
DropboxAPI<AndroidAuthSession> dDBApi;
Context dContext;
protected final ProgressDialog uDialog;
private long dFileLen;
private String SAVE_PATH;
private String mErrorMsg;
public UploadFile(Context context,DropboxAPI<AndroidAuthSession> mDBApi, String path) {
dDBApi=mDBApi;
dContext=context;
SAVE_PATH = path;
uDialog = new ProgressDialog(context);
uDialog.setMax(100);
uDialog.setMessage("Uploading Video Charade");
uDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
uDialog.show();
}
@Override
protected Boolean doInBackground(Void... params) {
FileInputStream inputStream = null;
try {
File file = new File(ShowVideo.path);
inputStream = new FileInputStream(file);
Entry newEntry = dDBApi.putFileOverwrite("/GAMES/GAME_BETWEEN_USER_A_USER_B/" + "PresentVideo.mp4", inputStream, file.length(), new ProgressListener() {
@Override
public long progressInterval() {
// Update the progress bar every half-second
return 500;
}
@Override
public void onProgress(long bytes, long total) {
dFileLen = total;
publishProgress(bytes);
}
});
} catch (DropboxUnlinkedException e) {
// This session wasn't authenticated properly or user unlinked
mErrorMsg = "This app wasn't authenticated properly.";
} catch (DropboxFileSizeException e) {
// File size too big to upload via the API
mErrorMsg = "This file is too big to upload";
} catch (DropboxPartialFileException e) {
// We canceled the operation
mErrorMsg = "Upload canceled";
} catch (DropboxServerException e) {
// Server-side exception. These are examples of what could happen,
// but we don't do anything special with them here.
if (e.error == DropboxServerException._401_UNAUTHORIZED) {
// Unauthorized, so we should unlink them. You may want to
// automatically log the user out in this case.
} else if (e.error == DropboxServerException._403_FORBIDDEN) {
// Not allowed to access this
} else if (e.error == DropboxServerException._404_NOT_FOUND) {
// path not found (or if it was the thumbnail, can't be
// thumbnailed)
} else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE) {
// user is over quota
} else {
// Something else
}
// This gets the Dropbox error, translated into the user's language
mErrorMsg = e.body.userError;
if (mErrorMsg == null) {
mErrorMsg = e.body.error;
}
} catch (DropboxIOException e) {
// Happens all the time, probably want to retry automatically.
mErrorMsg = "Network error. Try again.";
} catch (DropboxParseException e) {
// Probably due to Dropbox server restarting, should retry
mErrorMsg = "Dropbox error. Try again.";
} catch (DropboxException e) {
// Unknown error
mErrorMsg = "Unknown error. Try again.";
} catch (FileNotFoundException e) {
}
catch (Exception e) {
System.out.println("Something went wrong: " + e);
}
finally {
if (inputStream != null) {
try {
inputStream.close();
}
catch (IOException e) {
Log.d("TAG", "IOException" + e.getMessage());
}
}
Log.d("ErrorMsg", mErrorMsg);
}
return null;
}
@Override
protected void onProgressUpdate(Long... progress) {
int percent = (int)(100.0*(double)progress[0]/dFileLen + 0.5);
uDialog.setProgress(percent);
}
@Override
protected void onPostExecute(Boolean result) {
uDialog.dismiss();
super.onPostExecute(result);
Log.d("TAG","UDialog Should be dismissed");
}
}
公共类上载文件扩展异步任务{
DropboxAPI-dDBApi;
语境;
受保护的最终进度对话框;
私人长乐伦;
私有字符串保存路径;
私有字符串merrormg;
公共上载文件(上下文、DropboxAPI mDBApi、字符串路径){
dDBApi=mDBApi;
dContext=上下文;
保存路径=路径;
uDialog=新建进度对话框(上下文);
uDialog.setMax(100);
uDialog.setMessage(“上传视频字谜”);
uDialog.setProgressStyle(ProgressDialog.STYLE_水平);
uDialog.show();
}
@凌驾
受保护的布尔doInBackground(Void…params){
FileInputStream inputStream=null;
试一试{
File File=新文件(ShowVideo.path);
inputStream=新文件inputStream(文件);
Entry newEntry=dDBApi.putFileOverwrite(“/GAMES/GAMES\u\u USER\u B/”+“PresentVideo.mp4”,inputStream,file.length(),new ProgressListener()){
@凌驾
公共长时间间隔(){
//每半秒更新一次进度条
返回500;
}
@凌驾
public void onProgress(长字节,长总计){
dFileLen=总数;
出版进度(字节);
}
});
}捕获(DropboxUnlinkedException){
//此会话未正确验证或用户未链接
mErrorMsg=“此应用未正确验证。”;
}捕获(DropboxFileSizeException e){
//文件太大,无法通过API上载
mErrorMsg=“此文件太大,无法上载”;
}捕获(DropboxPartialFileE异常){
//我们取消了手术
mErrorMsg=“上传已取消”;
}捕获(DropboxServerException e){
//服务器端异常。这些是可能发生的情况的示例,
//但我们在这里对他们没有什么特别的处理。
如果(e.error==DropboxServerException.\u 401\u未经授权){
//未经授权,所以我们应该取消它们的链接。您可能想要
//在这种情况下,自动注销用户。
}否则如果(e.error==DropboxServerException.\u 403\u禁止){
//不允许访问此文件
}else if(e.error==DropboxServerException.\u 404\u未找到){
//未找到路径(或者如果是缩略图,则无法
//拇指钉)
}否则如果(e.error==DropboxServerException.\u 507\u存储不足){
//用户超过配额
}否则{
//别的
}
//这将获取Dropbox错误,并将其翻译成用户的语言
mErrorMsg=e.body.userError;
if(mErrorMsg==null){
mErrorMsg=e.body.error;
}
}捕获(DropboxIOE异常){
//经常发生,可能要自动重试。
mErrorMsg=“网络错误。请重试。”;
}捕获(DropboxParse异常){
//可能是由于Dropbox服务器重新启动,应该重试
mErrorMsg=“Dropbox错误。请重试。”;
}捕获(DropBoxexException e){
//未知错误
mErrorMsg=“未知错误。请重试。”;
}catch(filenotfounde异常){
}
捕获(例外e){
System.out.println(“出错:+e”);
}
最后{
如果(inputStream!=null){
试一试{
inputStream.close();
}
捕获(IOE异常){
Log.d(“TAG”、“IOException”+e.getMessage());
}
}
Log.d(“ErrorMsg”,mErrorMsg);
}
返回null;
}
@凌驾
受保护的void onProgressUpdate(长…进度){
整数百分比=(整数)(100.0*(双倍)进度[0]/dDellen+0.5);
uDialog.setProgress(百分比);
}
@凌驾
受保护的void onPostExecute(布尔结果){
uDialog.discouse();
super.onPostExecute(结果);
日志d(“标签”,“应撤销UDialog”);
}
}
这是我的Activity类,我从中调用UploadFile:
BuildSession和clearKeys方法尚未使用
public class ShowVideo extends Activity implements OnClickListener {
/** Dropbox Key and AccessType Information*/
final static private String APP_KEY = "XXXXXXXXXXXX";
final static private String APP_SECRET = "XXXXXXXXXXXX";
final static private AccessType ACCESS_TYPE = AccessType.APP_FOLDER;
final static private String ACCOUNT_PREFS_NAME = "prefs";
final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";
/**--------------------------------------------------------------*/
private DropboxAPI<AndroidAuthSession> mDBApi;
UploadFile upload;
static String path = "";
public static String fileName;
private VideoView ww;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); //Forces landscape orientation which is what the camera uses.
setContentView(R.layout.showvideo);
Button yesButton = (Button) findViewById(R.id.yesButton);
Button noButton = (Button) findViewById(R.id.NoButton);
yesButton.setOnClickListener(this);
noButton.setOnClickListener(this);
ww = (VideoView) findViewById(R.id.satisfiedVideoView);
path = getRealPathFromURI(CaptureVideo.uriVideo);
fileName = getFileNameFromUrl(path);
AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session = new AndroidAuthSession(appKeys, ACCESS_TYPE);
mDBApi = new DropboxAPI<AndroidAuthSession>(session);
if(!mDBApi.getSession().isLinked())
mDBApi.getSession().startAuthentication(ShowVideo.this);
}
private void playVideo(){
ww.setVideoURI(CaptureVideo.uriVideo);
ww.setMediaController(new MediaController(this));
ww.start();
ww.requestFocus();
}
public static String getFileNameFromUrl(String path) {
String[] pathArray = path.split("/");
return pathArray[pathArray.length - 1];
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.yesButton){
UploadFile upload = new UploadFile(ShowVideo.this,mDBApi,path);
upload.execute();
//if(upload.getStatus() == upload.){
//Intent intentHome = new Intent(ShowVideo.this, StartScreen.class);
//startActivity(intentHome);
//}
}
if(v.getId() == R.id.NoButton){
File file = new File(path);
boolean deleted = false;
deleted = file.delete();
Log.d("TAG", Boolean.toString(deleted));
Intent intent = new Intent(ShowVideo.this, CaptureVideo.class);
startActivity(intent);
}
}
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
/**DROPBOX-METHOD------------------------------------------*/
@Override
protected void onResume() {
super.onResume();
AndroidAuthSession session = mDBApi.getSession();
// The next part must be inserted in the onResume() method of the
// activity from which session.startAuthentication() was called, so
// that Dropbox authentication completes properly.
if (session.authenticationSuccessful()) {
try {
// Mandatory call to complete the auth
session.finishAuthentication();
// Store it locally in our app for later use
TokenPair tokens = session.getAccessTokenPair();
storeKeys(tokens.key, tokens.secret);
//setLoggedIn(true);
} catch (IllegalStateException e) {
showToast("Couldn't authenticate with Dropbox:" + e.getLocalizedMessage());
Log.i("TAG", "Error authenticating", e);
}
}
}
/**
* Shows keeping the access keys returned from Trusted Authenticator in a local
* store, rather than storing user name & password, and re-authenticating each
* time (which is not to be done, ever).
*
* @return Array of [access_key, access_secret], or null if none stored
*/
private String[] getKeys() {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
String key = prefs.getString(ACCESS_KEY_NAME, null);
String secret = prefs.getString(ACCESS_SECRET_NAME, null);
if (key != null && secret != null) {
String[] ret = new String[2];
ret[0] = key;
ret[1] = secret;
return ret;
} else {
return null;
}
}
/**
* Shows keeping the access keys returned from Trusted Authenticator in a local
* store, rather than storing user name & password, and re-authenticating each
* time (which is not to be done, ever).
*/
private void storeKeys(String key, String secret) {
// Save the access key for later
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
Editor edit = prefs.edit();
edit.putString(ACCESS_KEY_NAME, key);
edit.putString(ACCESS_SECRET_NAME, secret);
edit.commit();
}
private void clearKeys() {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
Editor edit = prefs.edit();
edit.clear();
edit.commit();
}
private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session;
String[] stored = getKeys();
if (stored != null) {
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE, accessToken);
} else {
session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE);
}
return session;
}
private void showToast(String msg) {
Toast error = Toast.makeText(this, msg, Toast.LENGTH_LONG);
error.show();
}
}
公共类ShowVideo扩展活动实现OnClickListener{
/**Dropbox键和访问类型信息*/
最终静态私有字符串APP_KEY=“xxxxxxxxxxx”;
最终静态私有字符串APP_SECRET=“xxxxxxxxxxx”;
最终静态私有AccessType ACCESS\u TYPE=AccessType.APP\u文件夹;
最终静态私有字符串帐户\u PREFS\u NAME=“PREFS”;
最终静态私有字符串访问密钥\u NAME=“访问密钥”;
最终静态私有字符串访问\u SECRET\u NAME=“访问\u SECRET”;
/**--------------------------------------------------------------*/
私有DropboxAPI mDBApi;
上传文件上传;
静态字符串路径=”;
公共静态字符串文件名;
私用视讯ww;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_Grait);//强制相机使用的横向方向。
setContentView(R.layout.showvideo);
dContext=context.getApplicationContext();
UploadFile upFile = new UploadFile( ActivityName.this, mDBApi, path);
dContext=context;
@Override
protected void onPostExecute(Boolean result) {
uDialog.dismiss();
Log.d("TAG","UDialog Should be dismissed");
super.onPostExecute(result);
}
if(v.getId() == R.id.NoButton){
File file = new File(path);
boolean deleted = false;
deleted = file.delete();
Log.d("TAG", Boolean.toString(deleted));
Intent intent = new Intent(ShowVideo.this, CaptureVideo.class);
startActivity(intent);
}