Android Questions (问题集锦)

开发过程中,解决问题集锦~


Android Framework Questions

Android External Storage Questions

happen W/ContextImpl: Failed to ensure directory
不要使用 context.getExternalFilesDir( String type) Api ,顺源码查看,发现此API,存在多个挂载区但不可用时,会打印警告信息。使用 Environment.getExternalStorageDirectory() 则不会
I follow the getExternalFilesDir() source

/**
 * Ensure that given directories exist, trying to create them if missing. If
 * unable to create, they are filtered by replacing with {@code null}.
 */
private File[] ensureExternalDirsExistOrFilter(File[] dirs) {
    File[] result = new File[dirs.length];
    for (int i = 0; i < dirs.length; i++) {
        File dir = dirs[i];
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                // recheck existence in case of cross-process race
                if (!dir.exists()) {
                    // Failing to mkdir() may be okay, since we might not have
                    // enough permissions; ask vold to create on our behalf.
                    final IMountService mount = IMountService.Stub.asInterface(
                            ServiceManager.getService("mount"));
                    try {
                        final int res = mount.mkdirs(getPackageName(), dir.getAbsolutePath());
                        if (res != 0) {
                            Log.w(TAG, "Failed to ensure " + dir + ": " + res);
                            dir = null;
                        }
                    } catch (Exception e) {
                        Log.w(TAG, "Failed to ensure " + dir + ": " + e);
                        dir = null;
                    }
                }
            }
        }
        result[i] = dir;
    }
    return result;

how to get ExternalFilesDir

public final class StorageUtil {

public static final String DIR_ANDROID = "Android";
private static final String DIR_DATA = "data";
private static final String DIR_FILES = "files";
private static final String DIR_CACHE = "cache";

@Nullable
public static synchronized File getExternalStorageAppFilesFile(Context context, String fileName) {
    if (context == null) return null;
    if (fileName == null) return null;
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        File dirs = buildExternalStorageAppFilesDirs(Environment.getExternalStorageDirectory().getAbsolutePath(), context.getPackageName());
        return new File(dirs, fileName);
    }
    return null;
}


public synchronized static File buildExternalStorageAppFilesDirs(String externalStoragePath, String packageName) {
    return buildPath(externalStoragePath, DIR_ANDROID, DIR_DATA, packageName, DIR_FILES);
}


public synchronized static File buildPath(String base, String... segments) {
    File cur = new File(base);
    for (String segment : segments) {
        cur = new File(cur, segment);
    }
    return cur;
}

Android Image Load Libraries

Glide

  1. happenCaused by: java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
    加上 Glide.with(context).isPaused() 去调用Glide.with(context).pauseRequests();
    即可
public static void resumeRequests(@NonNull final Context context) {
    if (!isContextDestroyed(context) && isPaused(context)) {
        Glide.with(context).resumeRequests();
    }
}
public static void pauseRequests(@NonNull final Context context) {
    if (!isContextDestroyed(context) && !isPaused(context)) {
        Glide.with(context).pauseRequests();
    }
}
public static boolean isPaused(@NonNull final Context context) {
    return isContextDestroyed(context) || Glide.with(context).isPaused();
}
private static boolean isContextDestroyed(@NonNull final Context context) {
    if (context instanceof Activity) {
        Activity activity = (Activity) context;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed()) {
            return true;
        }
    }
    return false;
}

Fragment

popBackStack 和 popBackStackImmediate 之坑

在复杂的Fragment 交互中,popBackStack 偶尔抛出java.lang.IllegalStateException Fragment already added
popBackStackImmediate 则偶尔抛出java.lang.IllegalStateException Can not perform this action after onSaveInstanceState
跟踪它们源码发现,popBackStack 是Handler异步出栈,popBackStackImmediate 是马上出栈的。我推荐用
popBackStackImmediate,问题来了如何解决上面问题呢

package android.support.v4.app;

/**
 * Created by lazy on 2017/8/23.
 */

public class VendingFragmentManager {

    /**
     * make sure no throws java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState ,HA HA
     *
     * @param fragmentManager
     */
    public static void allowStateLoss(FragmentManager fragmentManager) {
        ((FragmentManagerImpl) fragmentManager).noteStateNotSaved();
    }
}
FragmentManager fragmentManager = getSupportFragmentManager();
VendingFragmentManager.allowStateLoss(fragmentManager);
fragmentManager.popBackStackImmediate();
addMainFragment();

FragmentManagerImpl 类是用默认访问修饰符修饰的,新建android.support.v4.app 包就可以投机取巧访问了。

android studio not find usage

File->Invalidate and Restart

Android Studio 出现Unsupported major.minor version 52.0

* What went wrong:
A problem occurred evaluating project ':app'.
> java.lang.UnsupportedClassVersionError: com/android/build/gradle/AppPlugin : Unsupported major.minor version 52.0

在gradle.properties 使用jdk1.8 即可

org.gradle.java.home=/Applications/devtools/Android Studio.app/Contents/jre/jdk/Contents/Home

AppCompatTextView No static method getFont Error

java.lang.NoSuchMethodError: No static method getFont(Landroid/content/Context;ILandroid/util/TypedValue;ILandroid/widget/TextView;)Landroid/graphics/Typeface; in class Landroid/support/v4/content/res/ResourcesCompat; or its super classes (declaration of 'android.support.v4.content.res.ResourcesCompat'
at android.support.v7.widget.TintTypedArray.getFont(TintTypedArray.java:119)
                                                                        at android.support.v7.widget.AppCompatTextHelper.updateTypefaceAndStyle(AppCompatTextHelper.java:208)
                                                                        at android.support.v7.widget.AppCompatTextHelper.loadFromAttributes(AppCompatTextHelper.java:110)
                                                                        at android.support.v7.widget.AppCompatTextHelperV17.loadFromAttributes(AppCompatTextHelperV17.java:38)
                                                                        at android.support.v7.widget.AppCompatTextView.(AppCompatTextView.java:81)
                                                                        at android.support.v7.widget.AppCompatTextView.(AppCompatTextView.java:71)
                                                                        at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:103)
                                                                        at android.support.v7.app.AppCompatDelegateImplV9.createView(AppCompatDelegateImplV9.java:1024)
                                                                        at android.support.v7.app.AppCompatDelegateImplV9.onCreateView(AppCompatDelegateImplV9.java:1081)
                                                                        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:729)

更新 appcompat 版本就OK

你可能感兴趣的:(Android,Questions)