Tobias Tobias - 3 days ago 5
Android Question

Can not perform this action inside of onLoadFinished

I'm creating a new sample android app with one activity and many fragments.

At first i'm starting the "OverviewFragment" (my Dashboard) which should show some basic informations. My OverviewFragment loads the informations with an "AccountProvider" (ContentProvider). If the database is empty, the OverviewFragment should be replaces with my WelcomeFragment...

Here is some code:

public class OverviewFragment extends BaseFragment
implements LoaderManager.LoaderCallbacks {

private static final int LOADER_ACCOUNTS = 10;
private static final int LOADER_TRANSACTIONS = 20;

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

getLoaderManager().initLoader(LOADER_ACCOUNTS, null, this);
//getLoaderManager().initLoader(LOADER_TRANSACTIONS, null, this);
}

@Override
public Loader onCreateLoader(int id, Bundle args) {
Uri uri = null;
String[] projection = null;
String selection = null;
String[] selectionArgs = null;
String sortOrder = null;

switch (id) {
case LOADER_ACCOUNTS:
uri = WalletProvider.CONTENT_URI;
projection = new String[]{DBHelper.ACC_ID, DBHelper.ACC_TITLE};
sortOrder = DBHelper.ACC_TITLE;
break;
}
CursorLoader cl = new CursorLoader(getActivity(),
uri, projection, selection, selectionArgs, sortOrder);
return cl;
}

@Override
public void onLoadFinished(Loader loader, Object data) {
switch (loader.getId()) {
case LOADER_ACCOUNTS:
bindAccounts((Cursor) data);
break;
}

}

@Override
public void onLoaderReset(Loader loader) {

}

private void bindAccounts(Cursor cursor) {
boolean showCreateWallet = true;


if (cursor != null && cursor.moveToFirst()) {
showCreateWallet = false;
}

if (showCreateWallet) {
listener.changeFragment(new WalletCreateFragment());
}
}


and here my main activity

@Override
public void changeFragment(Fragment fragmentToLoad) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragmentToLoad)
.commit();
}


Now... if i'm starting my app with an empty database i get the error you see in the title..

I know that i should not change the fragment in the onLoadFinished function .... but where can i do it? :P

Sorry for my english =)

Answer

This is a bug of android. To solve this, use a Handler to replace/add/call a Fragment inside of onLoadFinished like this:

final int WHAT = 1;
Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {                    
        if(msg.what == WHAT) changeFragment(fragmentToLoad);            
    }
};
handler.sendEmptyMessage(WHAT);
Comments