1

I'm using Breeze 1.4.2 with Entity framework 5. This is my query:

var query = breeze.EntityQuery
        .from("TrendStudies")
        .where("Id", "==", studyId)
        .expand("Charts");

This works fine if I remove the .expand -part, but otherwise it fails with the following error message:

Object #<Object> has no method 'getProperty'

Apparently this error is thrown from the breeze function:

function updateRelatedEntityInCollection(relatedEntity, relatedEntities, targetEntity, inverseProperty) {
        if (!relatedEntity) return;
        // check if the related entity is already hooked up
        var thisEntity = relatedEntity.getProperty(inverseProperty.name);
        if (thisEntity !== targetEntity) {
            // if not - hook it up.
            relatedEntities.push(relatedEntity);
            relatedEntity.setProperty(inverseProperty.name, targetEntity);
        }
    }

My relatedEntity here is just

Object {Id: 104, TrendStudyId: 156, Order: 1, ChartClassId: 1}

So why is my relatedEntity missing the getProperty method here? Should it be initialized somewhere?


@VidarWahlberg your answer is good but let's say you have FragmentActivity where you run the task and you open new FragmentActivity that opens before async is over or your app is running on background(example: you clicked home). I suggest you create BaseActivity where you extend FragmentActivity and all your activities should extend it.

What is important?

In BaseActivity you need to have static FragmentManager fm;, as @VidarWahlberg mentioned in his answer, and use it in the child activity to show the DialogFragment.

What is the difference?

Instead of initializing fm = getSupportFragmentManager(); in onStart() method you need to do it in onResume(). It is needed because when you start the thread runing activity it's creating new instance of it and when starting the next activity it creates new instance of the BaseActivity where FragmenManager will be initialized and when you come back to the thread starting activity fm object be with the second activity(which is paused) instance. The application will crash because you will try showing dialog in already paused activity's view. You cannot change view of paused activity so you need to initialize whenever onResume() is called. onResume() is called also when activity starts so it's safe to initialize the FragmentManager there!

What elese we need to worry about?

You might think everything is ok but it's not. You may not realize it at first time but if your app is not at foreground(but at background) all of your activities are paused but the thread is already started and it's running. This is a problem because thread will continue and will try to show the DialogFragmernt(or let's say to change view of activity that is not on focus). So the solution is to track if app is on foreground or no. This can be done with PackageManager but it will require new permission in the manifest file(which users don't like and they may not want to install your app). The solution is to have static boolean isOnBackground = false; field that you change on every activity onResume() with isOnBackground = false; and in onPause() with isOnBackground = true;. This is not big change because BaseActivity is where we can do that. This is safe because every start of new activity creates new instance of the BaseActivity class but since the field is static it's created just once and is same for all instances. We need to check the state of isOnBackground before we start the body code of thread post method.

You may say that there can be problem because of delay between onPause() and onResume() but your app need to be designed in the way to start activity fast and not do long taking work on ui thread(need to be done on background thread). So if your app is designed good you will not have problems :)

You can use recursive call of the thread running method whenever app is not on foreground. This is safe and will not cause loop because when app's state are reseted(in need of memory) or app is stopped by user or android itself loop will be stopped because all app's instances will be freed from memory!

NOTE: Use the android support library!

Here goes the code:

BaseActivity.java

.......................
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
.......................

public class BaseActivity extends FragmentActivity {

    public static FragmentManager fm;
    public static boolean isOnBackground;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();
        BaseActivity.isOnBackground = false;
        BaseActivity.fm = getSupportFragmentManager();
    }

    @Override
    protected void onPause() {
        super.onPause();
        BaseActivity.isOnBackground = true;
    }
}

MainActivity.java

.....................
import android.support.v4.app.DialogFragment;
.....................

public class MainActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //This is just to call some second activity
        Button startNewActivity = (Button) findViewById(R.id.helloWorld);

        startNewActivity.setOnClickListener( new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,
                            SecondActivity.class);
                startActivity(intent);
            }
        });

        showEditDialog();
    }

    private void showEditDialog() {
        (new Handler()).postDelayed(new Runnable() {
            @Override
            public void run() {
                if(!BaseActivity.isOnBackground) {
                    DialogFragment myFragmentDialog = new DialogFragment();
                    myFragmentDialog.show(BaseActivity.fm,
                            "fragment_my_dialog");
                } else {
                    //this is optional
                    showEditDialog();
                }
            } 

        }, 15000);
    }
}
4

0 回答 0