2012-03-02 4 views
3

私はICSとウィジェットで遊んでいますが、本当に正しくデバッグできないような問題を遭遇しました。アイスクリームサンドイッチStrictMode

アプリケーションには主なアクティビティ(WidgetActivity)、ウィジェットの設定(WidgetConfigure)、プロバイダ(WidgetProvider)があります。ウィジェットのレイアウト(下のコード)には親LinearLayoutと子LinearLayoutsが2つあります。それらの子どもたちは両方とも目に見えないように設定されています。私のプロバイダのonUpdateでは、そのウィジェットのRemoteViewsオブジェクトをインスタンス化し、最初のLinearLayoutを可視に設定しようとします。

ウィジェットはホーム画面に表示されたときに表示されますが、2人の子供は表示されません(期待されます)。 onUpdateが呼び出されると、子は可視に設定されません。私が得るのは、StrictModeからウィジェットがその状態をディスクに書き込めないという警告の束です。読み書きのためのポリシー違反があります。私は実際にどこからでも読み書きをしているわけではないので、これはOSコールだと仮定します。

私の質問 - このStrictModeは視界を変えないように私のビューを引き起こしますか?大まかでも、StrictModeを使用すると、UIスレッドでコードが遅い場所を特定できます。しかし、私は、何が起こっているのかを理解せずに、StrictMode設定を盲目的に上書きしたり、新しいStrictMode設定をしたいだけではありません

adbが示すように、私のonReceiveが呼び出されています(180000msをもう一度待ちます)が、子ビューはvisibleに設定されていません。そして私はなぜそれがわからない。

ここにコードがあります。ウィジェットのレイアウト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> 

public class WidgetProvider extends AppWidgetProvider { 

    private static String TAG = "### WidgetProvider"; 

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
     super.onUpdate(context, appWidgetManager, appWidgetIds); 
     Log.d(TAG, "onUpdate"); 

     RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget); 
     Log.d(TAG, "Got Views"); 
     views.setViewVisibility(R.id.layout_one, View.VISIBLE); 
     Log.d(TAG, "Should've set visibility"); 
    } 
} 

 
D/### WidgetProvider( 522): onUpdate 
D/### WidgetProvider( 522): Got Views 
D/### WidgetProvider( 522): Should've set visibility 
I/ActivityManager( 84): Start proc com.android.quicksearchbox for broadcast com.android.quicksearchbox/.CorporaUpdateReceiver: pid=536 uid=10011 gids={3003} 
D/dalvikvm( 34): GC_EXPLICIT freed 37K, 4% free 9901K/10243K, paused 4ms+6ms 
D/dalvikvm( 84): GC_CONCURRENT freed 496K, 5% free 12726K/13383K, paused 11ms+43ms 
D/StrictMode( 84): StrictMode policy violation; ~duration=2436 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=151 violation=2 
D/StrictMode( 84): at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1074) 
D/StrictMode( 84): at libcore.io.BlockGuardOs.open(BlockGuardOs.java:94) 
D/StrictMode( 84): at libcore.io.IoBridge.open(IoBridge.java:390) 
D/StrictMode( 84): at java.io.FileOutputStream.(FileOutputStream.java:88) 
D/StrictMode( 84): at com.android.server.AppWidgetService.writeStateToFileLocked(AppWidgetService.java:1220) 
D/StrictMode( 84): at com.android.server.AppWidgetService.saveStateLocked(AppWidgetService.java:1204) 
D/StrictMode( 84): at com.android.server.AppWidgetService$2.onReceive(AppWidgetService.java:1503) 
D/StrictMode( 84): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728) 
D/StrictMode( 84): at android.os.Handler.handleCallback(Handler.java:605) 
D/StrictMode( 84): at android.os.Handler.dispatchMessage(Handler.java:92) 
D/StrictMode( 84): at android.os.Looper.loop(Looper.java:137) 
D/StrictMode( 84): at com.android.server.ServerThread.run(SystemServer.java:744) 
D/StrictMode( 84): StrictMode policy violation; ~duration=2301 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy=151 violation=1 
D/StrictMode( 84): at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1048) 
D/StrictMode( 84): at libcore.io.BlockGuardOs.write(BlockGuardOs.java:178) 
D/StrictMode( 84): at libcore.io.IoBridge.write(IoBridge.java:447) 
D/StrictMode( 84): at java.io.FileOutputStream.write(FileOutputStream.java:187) 
D/StrictMode( 84): at com.android.internal.util.FastXmlSerializer.flushBytes(FastXmlSerializer.java:212) 
D/StrictMode( 84): at com.android.internal.util.FastXmlSerializer.flush(FastXmlSerializer.java:233) 
D/StrictMode( 84): at com.android.internal.util.FastXmlSerializer.endDocument(FastXmlSerializer.java:183) 
D/StrictMode( 84): at com.android.server.AppWidgetService.writeStateToFileLocked(AppWidgetService.java:1266) 
D/StrictMode( 84): at com.android.server.AppWidgetService.saveStateLocked(AppWidgetService.java:1204) 
D/StrictMode( 84): at com.android.server.AppWidgetService$2.onReceive(AppWidgetService.java:1503) 
D/StrictMode( 84): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728) 
D/StrictMode( 84): at android.os.Handler.handleCallback(Handler.java:605) 
D/StrictMode( 84): at android.os.Handler.dispatchMessage(Handler.java:92) 
D/StrictMode( 84): at android.os.Looper.loop(Looper.java:137) 
D/StrictMode( 84): at com.android.server.ServerThread.run(SystemServer.java:744) 

答えて

4

理由は、実際には、StrictModeました。私はネットワークコードがServiceであることを確認し、ウィジェットのonUpdateではなく、この問題を回避しました。にもかかわらず、アンドロイドはStrictModeに違反してネットワークとディスクへのアクセスを訴えている。

この問題を回避するために、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); 
    } 
} 
1

ではなく、スレッドの方針を自分で管理するよりも、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 
    } 
}); 
関連する問題