I've just switched to using CursorLoaders and I'm having trouble writing tests that utilize them. Since using the CursorLoader methodology takes the querying off of the main thread getInstrumentation().waitForIdleSync() is returning before the adapter is being updated (or at least this is my theory). I'm trying to avoid this is all my tests
public void testUpdateList() throws InvalidRecord, InterruptedException {
ListView listView = frag.getListView();
// Verify list is empty
assertEquals(0, listView.getCount());
// Add transaction directly into database
transTable.addOccurrences(resolver, TestUtils.createMockTrans());
//Don't want to do this but it works.
synchronized (this) {
wait(500);
assertEquals(1, listView.getCount());
}
}
So my question is, is there a better way to test this functionality within the Android testing framework?
The solution I settled on was using the waitForCondition method within Robotium. Here is an example.
...
// Waits for 500 milliseconds for the condition to be meet.
// If it isn't meet within this time limit the result is false.
boolean isSatisfied = solo.waitForCondition( new Condition() {
public boolean isSatisfied() {
return listView.getCount() == 1;
}, 500);
//Then I check if the condition has been meet.
assertTrue(isSatisfied);
...
Related
I'm learning RxJava so please be gentle. I've watched the tutorials, done the reading, searched SO, however, I'm still having some problems transforming my AsyncTaskLoader. For some reason, I can't find a pattern of operators to achieve my task (although I think it's a common one). What I'm trying to do is the following: return an Observable my fragment could subscribe to. The observable should do the following on subscribe:
1) Fetch data from the local database by doing 2 queries, running some logic and returning results;
2) Fetching data from API;
3) Synchronising the new API data with the database;
4) Repeating step one and returning results;
So far I've transformed my db calls and my API calls to return observables. I'm trying to understand how I can emit the cold results and continue with the chain. I could probably keep the two operations separately, and use the same subscriber to subscribe to both? But I'm not sure how that would work if my new loader-replacement class returns an observable... Also I don't really need to process the results from the second observable - I just need for the first one to replay when the second one finished.
So far I have the following:
public Observable<StuffFetchResult> getColdStuff() {
return Observable.zip(mDataSource.listStuff(), mDataSource.listOtherStuff(),
(stuff, moreStuff) -> {
List<Stuff> mergedList = new ArrayList<>();
// do some merging stuff
return new StuffFetchResult(mergedList);
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
Assume I also have getHotStuff() that will do the API call and the synchronisation with the database, if that's the right approach, and return the same Observable. However, I'm stuck on the next step - how can I restart the first observable to replay once hotStuff has completed, without adding another subscriber?
EDIT:
I've made some progress and I think all I need now is to join it all up. I have my two methods:
1) getColdStuff() is pretty much as described above
2) getHotStuff() will do call to the API, synchronise with the database, and return an Observable. The idea was to call getColdStuff() again after getHotStuff() has finished in order to refresh the UI, so actual result returned from getHotStuff() can be ignored. All it needs to do is to trigger getColdStuff() once done.
I've tried the suggestion in the answer to and created the following:
BehaviorRelay<Observable<StuffFetchResult>> callSequence = BehaviorRelay.create();
Observable<StuffFetchResult> valueSequence = Observable.switchOnNextDelayError(callSequence.toSerialized());
valueSequence.subscribe(new Subscriber<StuffFetchResult>() {
#Override
public void onCompleted() {}
#Override
public void onError(Throwable e) {}
#Override
public void onNext(StuffFetchResult result) {
// UI stuff
}
});
callSequence.call(loader.getColdStuff());
I can subscribe to valueSequence here and use callSequence.call(loader.getColdStuff());, which will run the first method and produce results in onNext() of my subscription, which I can use for my UI. However, I'm not sure how to run getHotStuff() in parallel and also do a different action on it when it returns. Also getHotStuff() returns a different type of Observable so I can't really use the same callSequence?
EDIT 2
Using two subscribers, I can achieve the required behaviour I think. Not really sure if that's the right way to go about it though.
loader.getHotStuff()
.subscribeOn(Schedulers.io())
.subscribe( new Subscriber<Object>() {
#Override
public void onCompleted() {}
#Override
public void onError(Throwable e) {}
#Override
public void onNext(Object stuffWeDontCareAbout) {
callSequence.call(loader.getColdStuff());
}
});
if i understand your scenario correctly, you may want something like that -
BehaviorSubject<Observable<T> callSequence = BehaviorSubject.create();
Observable<T> valueSequence = Observable.swithOnNextDelayError(callSequence.toSerialized());
your subscriber will be listening to the valueSequence, and whenever you need to "restart", you will call this -
callSequence.onNext(call.cache()); // *call* is Observable<T>
(i leave the .subscribeOn/.observeOn configuration to you)
I am a newbie here, and I have searched online (and on stackoverflow) for the answer but I am still struggling to make it work.
What I am trying to do, is (1) update my list with fresh "posts" using an asyncronous task - thus allowing the user to continue using the app as I download new posts to their android.
I am struggling to get the updating task to work, and it could be tied to an obvious implementation problem (or not).
What I have is (1) A customized list (it allows "pull to refresh" - but as stated it is a problem that it is not refreshing any data at this point). (2) a custom AsyncTask that will theoretically populate more posts for the main list on the main screen.
Here is problem point in the list:
listView.setOnRefreshListener(new PullToRefreshListView.OnRefreshListener(listView) {
#Override
public void onRefresh() {
mylistAdapter.loadNewData(); //loads new data <-------------------
m_ptrlistView.postDelayed(new Runnable() {
#Override
public void run() {
m_ptrlistView.onRefreshComplete();
}
}, 2000);
////////////
Here is the function "loadNewData" in the adapter
public void loadNewData(PullToRefreshListView List){
//load new stuff
new AsyncFetchMore(list).execute();
// MANDATORY: Notify that the data has changed
notifyDataSetChanged();
return;
}
And... my asyncTask that is extended's implementation
#Override
protected Object doInBackground() {
try {
//simulating a long task
Thread.sleep(5000);
} catch (InterruptedException e) {
Log.d("Notes", "Thread failed to sleep");
}
//create dummy posts for testing
for ( int i = 12; i < 24; i++ ) {
Post pNewPost = new Post();
pNewPost.setText("POST # " + i);
m_alNewPosts.add(pNewPost);
}
return null;
}
///////////////////////////////
Perhaps I'm approaching it all wrong. I'm having doubts... But I just don't know what the right next step is and I am pretty lost here! Can you give me any tips?
It looks like you arent doint anything with results that are returned by your async task. But before you go to fix it, please consider using Loaders - they are asyncronous and made specifically for your purpouse - getting data for Fragment/Activity. Here is documentation for them. It looks like you might have a fair amount of refactoring to do if you want to implement them, but its well worth it - its the right way. hope this helps.
You are calling notifyDataSetChanged() right after you start your Async thread, which hasn't populated your data. Call notifyDataSetChanged() after the data has been updated. Check out the examples in ApiDemos in the samples directory of the SDK.
I'm developing a relatively small 2D game for Android right now. To process the collision detections as efficient as possible, I've created multiple threads working on the calculations:
Thread #1: Main handling of the frames, limiting them to X per second, handling the Bitmaps (rotate, draw...)
Thread #2: Calculate some collisions
Thread #3: Calculate other collisions
What I need is some sort of synchronization, but I am unsure of what's the best way to achieve this. I thought of something like this:
Thread #1:
public class Thread1 imlements Runnable {
public static ArrayList<Boolean> ResponseList = new ArrayList<Boolean>();
static {
ResponseList.add(0, false); // index 0 -> thread 1
ResponseList.add(1, false); // index 1 -> thread 2
}
public void run() {
boolean notFinished;
while(!isInterrupted() && isRunning) {
notFinished = true;
// do thread-business, canvas stuff, etc, draw
while(notFinished) {
notFinished = false;
for(boolean cur: ResponseList) {
if(!cur) notFinished = true;
}
// maybe sleep 10ms or something
}
}
}
}
And in the other calculation threads something like:
public class CalcThread implements Runnable {
private static final INDEX = 0;
public void run() {
while(isRunning) {
ResponseList.set(INDEX, false);
executeCalculations();
ResponseList.set(INDEX, true);
}
}
}
Or would it be faster (as this is what I'm concerned about) to use a Looper/Handler combination? Just read about this, but I'm not sure yet how to implement this. Would look deeper into this is this would be the more efficient method.
I don't know if it is going to be faster, but it will be more reliable for sure. For example, you are using ArrayList from multiple threads without serialization and ArrayList is not thread-safe
Handler is just one of the available mechanisms, I would recommend you to study java.util.concurrent - there is no point in reinventing the wheel, many synchronization primitives are already available. Perhaps Future would work for you
A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation.
I'm designing out a module in Android that does some processing and then writes to the database using ORMLite transactions. In particular, my background code will be something like:
public class BackgroundOperation implements Runnable {
#Override
public void run() {
//Do some stuff
//Write to the database in a transaction
try {
ORMHelper h = ORMHelper.getDefaultOrmHelper();
final MyModel modelObj = h.myModelDao.queryForId(someId);
TransactionManager.callInTransaction(
h.getConnectionSource(),
new Callable<Void>() {
public Void call() throws Exception {
modelObj.col1 = 10;
modelObj.col2 = "hello";
h.myModel2Dao.update(modelObj);
h.myModel2Dao.create(new MyModel2("a", "b"));
return null;
}
}
);
}
catch (Exception e) {
return null;
}
}
}
This runnable will then be executed by being submitted to a ThreadPoolExecutor. I want to be able to cancel the background thread if needed and am trying to make sure that if the operation is cancelled, then the transaction will simply fail and do nothing. For example, if I do this:
Future f = myThreadPoolExecutor.submit(new BackgroundOperation());
//Some time later
f.cancel(true);
Can I be sure that it will be an all or nothing deal with the transaction in ORMLite. That is, there is no cleanup needed and my modelObj will have either both col1 and col2 set or neither set? Do I have to do anything special when catching the InterruptedException in the Runnable to handle the case when a task is cancelled in this way, or can I simply exit?
If you call f.cancel(true), all that does is interrupt the Thread which causes wait(), sleep(), and some other methods to throw InterruptedException. It will not cancel the database transaction underway.
If you want, you can check for the interrupted bit in the middle of your IO operations:
h.myModel2Dao.update(modelObj);
if (Thread.currentThread().isInterrupted()) {
throw new RuntimeException("Thread was interrupted");
}
h.myModel2Dao.create(new MyModel2("a", "b"));
For more information about what happens when a thread is interrupted see here:
What does java.lang.Thread.interrupt() do?
Transactions are for when you are updating multiple objects as a single unit or writing to multiple tables. See the documentation about transactions which has an example of updating an Account and an Order inside of a transaction.
Also, you do not need to use a transaction if you are updating multiple fields in the same row. The update statement is considered to be a single unit and the database should ensure that the row gets updated atomically. Only if you are updating multiple different rows either in the same table or in separate tables do you need a transaction.
ORMLite will utilize the sqlite transactions under the covers. This is most likely a double phase commit which only allows you to commit a transaction as an entire unit.
In short, you can be assured that col1 and col2 will only be modified as a single atomic unit. Also, it if is interrupted the commit will fail and the changes to col1 and col2 will be rolled back.
I'm just picking up android development to make a game. Touched it before, but only picked up the basics. I'm a bit confused how to set up a main loop. I've been into XNA (C#) and I love the separated update/draw loop.
I was wondering how a typical android gameloop works? I've searched online and came across 2 methods:
public void run() {
while (running) {
//Method 1: update is called here
view.update();
Canvas c = null;
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
//Method 2: update is called inside view.onDraw
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
}
}
Let's take the updating of game entities as an example for the 2 methods:
//METHOD1
public void onDraw(Canvas canvas)
{
for (GameEntity entity : entities)
{
entity.update();
entity.draw(canvas);
}
}
//END METHOD 1
//METHOD 2
public void update()
{
for (GameEntity entity : entities)
{
entity.update();
}
}
public void draw(Canvas canvas)
{
for (GameEntity entity : entities)
{
entity.draw(canvas);
}
}
//END METHOD 2
Now I have no experience with threads whatsoever, so I have no idea how XNA does the update/draw loops behind the screens in xna.
But using method 1, I would have to loop through all the entities twice, once for updating and another time for seperate drawing. I'm afraid this will kill the performance, but I háve seen this in samples online.
Am I missing something or am I right and is method 2 the best performance wise?
It matters not how many times you loop since it only matters how many actions you do. And the amount of actions done are basicly the same. since the second "for" only adds an one more supposed "if" for each entety. So its not much.
But it gives you the ability to do only one of the actions and not forced to do both.
for example: if I want the game to update 60 times per sec but only draw 40 fps, I can only do that in method 2. This allows you to have a more fluid game with less calculations, but only if you use it right.
If you have the darw and update happen at the same rate, then it is stupid to split them