我遇到了这个问题,并在这里和其他与此问题相关的帖子中提出了很多帖子。
此应用程序以android 16为目标,但min设置为8.所以我使用Android支持库访问更新的apis。
我有一个活动加载一个ListFragment片段。如果您在横向模式下在平板电脑上运行,则第一个片段(单击列表项时)将以2窗格布局加载第二个片段。如果在手机上,新活动会加载第二个片段。
第二个片段使用CursorLoader访问ContentProvider作为其后备数据存储。当从自己的活动中调用此片段时,没有问题。但是,当它处于2窗格布局时,CursorLoader将因上述异常而失败。
以下是代码:
public class ProgramGroupFragment extends MythtvListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = ProgramGroupFragment.class.getSimpleName();
private ProgramCursorAdapter adapter;
private String programGroup = "*";
public ProgramGroupFragment() { }
@Override
public Loader<Cursor> onCreateLoader( int id, Bundle args ) {
String[] projection = { BaseColumns._ID, ProgramConstants.FIELD_TITLE, ProgramConstants.FIELD_SUB_TITLE };
String[] selectionArgs = { programGroup };
CursorLoader cursorLoader = new CursorLoader( getActivity(), ProgramConstants.CONTENT_URI, projection, ProgramConstants.FIELD_TITLE + "=?", selectionArgs, ProgramConstants.FIELD_SUB_TITLE );
return cursorLoader;
}
@Override
public void onLoadFinished( Loader<Cursor> loader, Cursor cursor ) {
Log.v( TAG, "onLoadFinished : enter" );
adapter.swapCursor( cursor );
}
@Override
public void onLoaderReset( Loader<Cursor> loader ) {
adapter.swapCursor( null );
}
@Override
public void onActivityCreated( Bundle savedInstanceState ) {
super.onActivityCreated( savedInstanceState );
adapter = new ProgramCursorAdapter(
getActivity().getApplicationContext(), R.layout.program_row,
null, new String[] { ProgramConstants.FIELD_SUB_TITLE }, new int[] { R.id.program_sub_title },
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER );
setListAdapter( adapter );
getLoaderManager().initLoader( 0, null, this );
}
public void loadPrograms( String name ) {
programGroup = name;
try {
getLoaderManager().restartLoader( 0, null, this );
} catch( Exception e ) {
Log.w( TAG, e.getLocalizedMessage(), e );
}
}
@Override
public void onListItemClick( ListView l, View v, int position, long id ) {
super.onListItemClick( l, v, position, id );
Intent i = new Intent( getActivity(), VideoActivity.class );
i.putExtra( VideoActivity.EXTRA_PROGRAM_KEY, id );
startActivity( i );
}
private class ProgramCursorAdapter extends SimpleCursorAdapter {
public ProgramCursorAdapter( Context context, int layout, Cursor c, String[] from, int[] to, int flags ) {
super( context, layout, c, from, to, flags );
}
@Override
public View getView( int position, View convertView, ViewGroup parent ) {
View row = super.getView( position, convertView, parent );
getCursor().moveToPosition( position );
try {
int idIndex = getCursor().getColumnIndexOrThrow( BaseColumns._ID );
int titleIndex = getCursor().getColumnIndexOrThrow( ProgramConstants.FIELD_TITLE );
int subTitleIndex = getCursor().getColumnIndexOrThrow( ProgramConstants.FIELD_SUB_TITLE );
int id = getCursor().getInt( idIndex );
String title = getCursor().getString( titleIndex );
String subTitle = getCursor().getString( subTitleIndex );
if( row == null ) {
LayoutInflater inflater = getActivity().getLayoutInflater();
row = inflater.inflate( R.layout.program_row, parent, false );
}
TextView t = (TextView) row.findViewById( R.id.program_sub_title );
t.setText( !"".equals( subTitle ) ? subTitle : title );
} catch( Exception e ) {
Log.e( TAG, "getView : error", e );
}
return row;
}
}
}
问题出现在loadPrograms方法中,特别是行:
getLoaderManager().restartLoader( 0, null, this );
这是抛出IllegalStateException。在查看了文档和大量示例之后,我从未见过这个问题而且必须被抓住才能继续。
我将代码包装在try / catch块中只是为了看看会发生什么,令我惊讶的是,应用程序按预期工作。
编辑: 以下是建立2窗格布局的活动代码:
public class RecordingsActivity extends AbstractRecordingsActivity implements RecordingsFragment.OnProgramGroupListener {
private static final String TAG = RecordingsActivity.class.getSimpleName();
private static final int REFRESH_ID = Menu.FIRST + 2;
private long requestId;
private BroadcastReceiver requestReceiver;
private DvrServiceHelper mDvrServiceHelper;
@Override
public void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_dvr_recordings );
RecordingsFragment recordingsFragment = (RecordingsFragment) getSupportFragmentManager().findFragmentById( R.id.fragment_dvr_program_groups );
recordingsFragment.setOnProgramGroupListener( this );
}
@TargetApi( 11 )
@Override
public boolean onCreateOptionsMenu( Menu menu ) {
Log.v( TAG, "onCreateOptionsMenu : enter" );
MenuItem refresh = menu.add( Menu.NONE, REFRESH_ID, Menu.NONE, "Refresh" );
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
refresh.setShowAsAction( MenuItem.SHOW_AS_ACTION_IF_ROOM );
}
return true;
}
/* (non-Javadoc)
* @see org.mythtv.client.ui.dvr.AbstractRecordingsActivity#onOptionsItemSelected(android.view.MenuItem)
*/
@Override
public boolean onOptionsItemSelected( MenuItem item ) {
switch( item.getItemId() ) {
case REFRESH_ID:
requestId = mDvrServiceHelper.getRecordingedList();
return true;
}
return super.onOptionsItemSelected( item );
}
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter( DvrServiceHelper.ACTION_REQUEST_RESULT );
requestReceiver = new BroadcastReceiver() {
@Override
public void onReceive( Context context, Intent intent ) {
long resultRequestId = intent.getLongExtra( DvrServiceHelper.EXTRA_REQUEST_ID, 0 );
if( resultRequestId == requestId ) {
int resultCode = intent.getIntExtra( DvrServiceHelper.EXTRA_RESULT_CODE, 0 );
if( resultCode == 200 ) {
Log.d( TAG, "Updating UI with new data" );
} else {
Log.d( TAG, "error occurred" );
}
} else {
Log.d( TAG, "Result is NOT for our request ID" );
}
}
};
mDvrServiceHelper = DvrServiceHelper.getInstance( this );
registerReceiver( requestReceiver, filter );
}
/* (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onPause()
*/
@Override
public void onPause() {
super.onPause();
// Unregister for broadcast
if( null != requestReceiver ) {
try {
unregisterReceiver( requestReceiver );
requestReceiver = null;
} catch( IllegalArgumentException e ) {
Log.e( TAG, e.getLocalizedMessage(), e );
}
}
}
public void onProgramGroupSelected( String programGroup ) {
Log.d( TAG, "onProgramGroupSelected : enter" );
if( null != findViewById( R.id.fragment_dvr_program_group ) ) {
FragmentManager manager = getSupportFragmentManager();
ProgramGroupFragment programGroupFragment = (ProgramGroupFragment) manager.findFragmentById( R.id.fragment_dvr_program_group );
FragmentTransaction transaction = manager.beginTransaction();
if( null == programGroupFragment ) {
Log.v( TAG, "onProgramGroupSelected : creating new programGroupFragment" );
programGroupFragment = new ProgramGroupFragment();
transaction
.add( R.id.fragment_dvr_program_group, programGroupFragment )
.setTransition( FragmentTransaction.TRANSIT_FRAGMENT_OPEN )
.addToBackStack( null )
.commit();
}
programGroupFragment.loadPrograms( programGroup );
} else {
Intent i = new Intent( this, ProgramGroupActivity.class );
i.putExtra( ProgramGroupActivity.EXTRA_PROGRAM_GROUP_KEY, programGroup );
startActivity( i );
}
}
}
onProgramGroupSelected上的Listener方法是确定单个vs 2窗格布局的位置。单击左侧疼痛中的列表项时将调用侦听器。
任何人都可以解释为什么会发生这种异常吗?
项目的完整代码位于https://github.com/MythTV-Android/mythtv-for-android
答案 0 :(得分:1)
我经历过类似的事情。对我来说,在使用上下文时似乎有助于避免使用ApplicationContext
。尝试在不使用ProgramCursorAdapter
的情况下创建getApplicationContext()
。