Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 冰淇淋三明治_Android_Android Widget - Fatal编程技术网

Android 冰淇淋三明治

Android 冰淇淋三明治,android,android-widget,Android,Android Widget,我在玩IC和小部件,偶然发现了一个我似乎无法正确调试的问题 应用程序有一个主活动(WidgetActivity)、一个小部件配置(WidgetConfigure)和一个提供程序(WidgetProvider)。小部件的布局(下面的代码)有一个父LinearLayout和两个子LinearLayout。这两个孩子都被设置为不可见。在我的提供者的onUpdate中,我实例化了该小部件的RemoteViews对象,并尝试将第一个LinearLayout设置为可见 小部件显示在主屏幕上时,但两个孩子不显

我在玩IC和小部件,偶然发现了一个我似乎无法正确调试的问题

应用程序有一个主活动(WidgetActivity)、一个小部件配置(WidgetConfigure)和一个提供程序(WidgetProvider)。小部件的布局(下面的代码)有一个父LinearLayout和两个子LinearLayout。这两个孩子都被设置为不可见。在我的提供者的
onUpdate
中,我实例化了该小部件的RemoteViews对象,并尝试将第一个LinearLayout设置为可见

小部件显示在主屏幕上时,但两个孩子不显示(预期)。调用
onUpdate
时,子项未设置为可见。在adb中,我得到的是来自StrictMode的一系列警告,关于小部件无法将其状态写入磁盘。读写操作违反了策略。因为我实际上没有在任何地方进行读写操作,所以我假设这是一个操作系统调用

我的问题-这种模式是否会导致我的视图不改变可见性?我明白,从一个粗略的、高层次的角度来看,StrictMode允许我识别UI线程中的慢代码。但我不想在不了解情况下盲目地覆盖或设置新的StrictMode设置

如adb所示,我的onReceive正在被调用(如果您再次等待180000毫秒),但我的子视图未设置为可见。我不知道为什么

这是密码。小部件布局xml、提供程序、adb跟踪:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFF"
    android:orientation="vertical" >

    <include layout="@layout/widget_next_season" />

    <include layout="@layout/widget_upcoming_game" />

</LinearLayout>

D/####WidgetProvider(522):未更新 D/####WidgetProvider(522):获取视图 D/####WidgetProvider(522):应该设置可见性 I/ActivityManager(84):为广播com.android.quicksearchbox/.CorporateUpdateReceiver启动proc com.android.quicksearchbox:pid=536 uid=10011 gids={3003} D/dalvikvm(34):GC_显式释放37K,4%释放9901K/10243K,暂停4ms+6ms D/dalvikvm(84):GC_并发释放496K,5%释放12726K/13383K,暂停11ms+43ms D/StrictMode(84):StrictMode策略违反~持续时间=2436毫秒:android.os.StrictMode$StrictModeDiskReadViolation:policy=151 violation=2 D/StrictMode(84):位于android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1074) D/StrictMode(84):位于libcore.io.BlockGuardOs.open(BlockGuardOs.java:94) D/StrictMode(84):位于libcore.io.IoBridge.open(IoBridge.java:390) D/StrictMode(84):位于java.io.FileOutputStream。(FileOutputStream.java:88) D/StrictMode(84):位于com.android.server.AppWidgetService.writeStateToFileLocked(AppWidgetService.java:1220) D/StrictMode(84):位于com.android.server.AppWidgetService.saveStateLocked(AppWidgetService.java:1204) D/StrictMode(84):位于com.android.server.AppWidgetService$2.onReceive(AppWidgetService.java:1503) D/StrictMode(84):在android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728) D/StrictMode(84):位于android.os.Handler.handleCallback(Handler.java:605) D/StrictMode(84):位于android.os.Handler.dispatchMessage(Handler.java:92) D/StrictMode(84):位于android.os.Looper.loop(Looper.java:137) D/stricmode(84):位于com.android.server.ServerThread.run(SystemServer.java:744) D/StrictMode(84):StrictMode策略违反~持续时间=2301毫秒:android.os.StrictMode$StrictModeDiskWriteVolation:policy=151冲突=1 D/StrictMode(84):位于android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1048) D/StrictMode(84):位于libcore.io.BlockGuardOs.write(BlockGuardOs.java:178) D/stricmode(84):位于libcore.io.IoBridge.write(IoBridge.java:447) D/StrictMode(84):位于java.io.FileOutputStream.write(FileOutputStream.java:187) D/StrictMode(84):位于com.android.internal.util.FastXmlSerializer.flushBytes(FastXmlSerializer.java:212) D/StrictMode(84):位于com.android.internal.util.FastXmlSerializer.flush(FastXmlSerializer.java:233) D/StrictMode(84):位于com.android.internal.util.FastXmlSerializer.endDocument(FastXmlSerializer.java:183) D/StrictMode(84):位于com.android.server.AppWidgetService.writeStateToFileLocked(AppWidgetService.java:1266) D/StrictMode(84):位于com.android.server.AppWidgetService.saveStateLocked(AppWidgetService.java:1204) D/StrictMode(84):位于com.android.server.AppWidgetService$2.onReceive(AppWidgetService.java:1503) D/StrictMode(84):在android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728) D/StrictMode(84):位于android.os.Handler.handleCallback(Handler.java:605) D/StrictMode(84):位于android.os.Handler.dispatchMessage(Handler.java:92) D/StrictMode(84):位于android.os.Looper.loop(Looper.java:137) D/stricmode(84):位于com.android.server.ServerThread.run(SystemServer.java:744)
事实上,原因在于严格的模式。我已经解决了这个问题,确保我的网络代码在
服务中,而不是在小部件的
更新中。尽管如此,Android仍然抱怨违反了严格的网络和光盘访问模式

为了解决这个问题,我修改了StrictMode策略,并在完成后重置它。我只是围绕网络代码调用这些函数

/**
 * Prevent exceptions from doing disk and network operations in a service
 */
protected static void setPermissiveThreadPolicy() {
    // set StrictMode to allow network/disk in service
    oldThreadPolicy = StrictMode.getThreadPolicy();
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(oldThreadPolicy).permitNetwork().permitDiskReads().permitDiskWrites().build());
}

/**
 * Reset thread policy to previously known state for consistency
 */
protected static void resetThreadPolicy() {
    if (oldThreadPolicy != null) {
        // reset to old policy
        StrictMode.setThreadPolicy(oldThreadPolicy);
    }
}

为了补充jlindenbaum的贡献,而不是自己管理线程策略,这里有一个很好的助手类,它可以确保您不会忘记重置线程策略

public class ThreadPolicyManager {

// ========== Singleton ==========
private static ThreadPolicyManager sInstance;
public static ThreadPolicyManager getInstance()
{
    if(sInstance == null)
    {
        sInstance = new ThreadPolicyManager();
    }
    return sInstance;
}

private ThreadPolicyManager(){}

// ========== Class ==========

private StrictMode.ThreadPolicy mPreviousThreadPolicy;

/**
 * Prevent exceptions from doing disk and network operations in a service
 */
private void setPermissiveThreadPolicy() {
    mPreviousThreadPolicy = StrictMode.getThreadPolicy();
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(mPreviousThreadPolicy).permitNetwork().permitDiskReads().permitDiskWrites().build());
}

/**
 * Reset thread policy to previously known state for consistency
 */
private void resetThreadPolicy() {
    if (mPreviousThreadPolicy != null) {
        StrictMode.setThreadPolicy(mPreviousThreadPolicy);
    }
}

/**
 * This will temporarily set the thread policy to permissive,
 * execute the unit of work, and then reset the thread policy
 */
public void executePermissiveUnit(PermissiveUnit unit)
{
    setPermissiveThreadPolicy();
    unit.executeUnitOfWork();
    resetThreadPolicy();
}

// ========= PermissiveUnit ========

/**
 * This is a functor to allow a unit of work to be executed
 * permissively
 */
public static abstract class PermissiveUnit{
    public abstract void executeUnitOfWork();
}

}
使用它:

ThreadPolicyManager.getInstance().executePermissiveUnit(new ThreadPolicyManager.PermissiveUnit(){
    @Override
    public void executeUnitOfWork() {
        //TODO whatever needs to be executed
    }
});
public class ThreadPolicyManager {

// ========== Singleton ==========
private static ThreadPolicyManager sInstance;
public static ThreadPolicyManager getInstance()
{
    if(sInstance == null)
    {
        sInstance = new ThreadPolicyManager();
    }
    return sInstance;
}

private ThreadPolicyManager(){}

// ========== Class ==========

private StrictMode.ThreadPolicy mPreviousThreadPolicy;

/**
 * Prevent exceptions from doing disk and network operations in a service
 */
private void setPermissiveThreadPolicy() {
    mPreviousThreadPolicy = StrictMode.getThreadPolicy();
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(mPreviousThreadPolicy).permitNetwork().permitDiskReads().permitDiskWrites().build());
}

/**
 * Reset thread policy to previously known state for consistency
 */
private void resetThreadPolicy() {
    if (mPreviousThreadPolicy != null) {
        StrictMode.setThreadPolicy(mPreviousThreadPolicy);
    }
}

/**
 * This will temporarily set the thread policy to permissive,
 * execute the unit of work, and then reset the thread policy
 */
public void executePermissiveUnit(PermissiveUnit unit)
{
    setPermissiveThreadPolicy();
    unit.executeUnitOfWork();
    resetThreadPolicy();
}

// ========= PermissiveUnit ========

/**
 * This is a functor to allow a unit of work to be executed
 * permissively
 */
public static abstract class PermissiveUnit{
    public abstract void executeUnitOfWork();
}

}
ThreadPolicyManager.getInstance().executePermissiveUnit(new ThreadPolicyManager.PermissiveUnit(){
    @Override
    public void executeUnitOfWork() {
        //TODO whatever needs to be executed
    }
});