0

我正在尝试通过 AsyncTask 将文件上传到保管箱,但出现窗口泄漏错误:

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

我看了这里并明白这是因为我的活动已退出并且进度对话框仍然存在。我不明白为什么我的活动会退出。它只是一个带有按钮的屏幕,可以按下以上传文件。我正在使用几乎相同的代码从保管箱下载文件,并且效果很好。

有什么建议么?提前致谢!

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");
    }

}

这是我调用 UploadFile 的 Activity 类:尚未使用方法 buidSession 和 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();
    }


}
4

2 回答 2

0

调用super.onPostExexute(result)uDialog.dismiss();

@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);
        }

在 onPostExecute 触发器中,因为它在不等待 AsyncTask 完成的情况下执行。这意味着您必须传递 的值,v.getId()这样您才能实现相同的功能。

于 2013-05-16T14:56:34.480 回答
0

试试这个,在你的构造函数中你不会得到这样的上下文:

dContext=context.getApplicationContext();

但尝试传递您开始异步任务的活动

UploadFile upFile = new UploadFile( ActivityName.this, mDBApi, path);

所以在你的构造函数中你现在只有:

dContext=context;
于 2013-05-16T14:36:08.897 回答