is SQLiteDatabase syncronous or async? - java

I have an app that opens a new intent. The new intent inserts some rows on the datadabase, then finish(); it and come back to the first screen where the data should have refreshed with the new row. The code I have do not work on execution but works when debuging... so maybe there is some lag somewhere... maybe? how to wait for the query to finish?
Here is my code:
on the first screen:
setting the adapter and onResume
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
v= inflater.inflate(R.layout.filters_fragment,container,false);
createFragmentWidgets();
myrecyclerview = (RecyclerView) v.findViewById(R.id.contact_recycleview);
recyclerAdapter = new RecyclerViewAdapterFilters(getContext(), lstFilters);
myrecyclerview.setLayoutManager(new LinearLayoutManager((getActivity())));
myrecyclerview.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
myrecyclerview.setAdapter(recyclerAdapter);
return v;
}
#Override
public void onResume()
{
// After a pause OR at startup
super.onResume();
lstFilters = mydb.getAllFilters("BL");
recyclerAdapter.notifyDataSetChanged();
}
the getAllFilters method on the DB class
public List<Filter> getAllFilters(String type) {
List<Filter> lstFilter = new ArrayList<>();
//hp = new HashMap();
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery( "select * from " + FILTERS_TABLE_NAME+" where type='"+type+"'", null );
res.moveToFirst();
while(res.isAfterLast() == false){
lstFilter.add(new Filter (res.getInt(res.getColumnIndex(FILTERS_COLUMN_ID)),
res.getString(res.getColumnIndex(FILTERS_COLUMN_NAME)),
res.getString(res.getColumnIndex(FILTERS_COLUMN_NUMBER)),
res.getString(res.getColumnIndex(FILTERS_COLUMN_PHOTO)),
res.getString(res.getColumnIndex(FILTERS_COLUMN_TYPE))));
res.moveToNext();
}
res.close();
db.close();
return lstFilter;
}
any ideas?

After you refresh your list, it should be enough to call notifyDataSetChanged(), however, I usually just reset the adapter:
adapter = new ClaimListAdapter(this, thisContext, claimItems);
mClaimList.setAdapter(adapter);

since you're replacing the contents of the list, call adapter.notifyDataSetChanged() to refresh the entire list.

Related

Android RecyclerView not refreshing on adapter.notifyDataSetChanged

Classic problem here: I'm fetching some data from a database into a recyclerView using an ArrayList of custom objects (and this happens in a Fragment, not in the Main Activity). Everything works like a charm until I try to refresh the recyclerView using a spinner that changes how the data is sorted. I know the data is fed to the recyclerView correctly. What am I doing wrong? API level is 19.
This is how the fetch is done:
public ArrayList<LEGOSet> getSets(String conditions) {
ArrayList<LEGOSet> sets = new ArrayList<>();
Cursor cursor = database.rawQuery("SELECT * FROM Sets " + conditions, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
LEGOSet set = new LEGOSet(cursor.getInt(0), cursor.getString(1), cursor.getInt(2), cursor.getInt(3), cursor.getString(4), cursor.getDouble(5),
cursor.getDouble(6), cursor.getDouble(7), cursor.getDouble(8), cursor.getDouble(9), cursor.getDouble(10), cursor.getString(11),
cursor.getString(12), cursor.getString(13), cursor.getString(14), cursor.getInt(15), cursor.getInt(16), cursor.getInt(17));
sets.add(set);
cursor.moveToNext();
}
cursor.close();
return sets;
}
The fragment with the data being pulled, the recyclerView being set up and with the spinner onItemSelected code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_catalog, container, false);
// pull data from database
sets = dbManager.getSets("order by pieces desc");
// set up the RecyclerView
final RecyclerView recyclerView = root.findViewById(R.id.rvSets);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new MyRecyclerViewAdapter(getActivity(), sets, portrait);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
// add dividers
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), 1);
dividerItemDecoration.setDrawable(new ColorDrawable(getResources().getColor(R.color.colorSubtle)));
recyclerView.addItemDecoration(dividerItemDecoration);
// spinner Product Sorting
spinnerProductSorting = root.findViewById(R.id.spinnerProductSorting);
spinnerProductSorting.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
String s = spinnerProductSorting.getSelectedItem().toString();
switch(s)
{
case "Biggest first":
sets = dbManager.getSets("order by pieces desc");
Toast.makeText(getContext(),sets.get(0).getName(), Toast.LENGTH_SHORT).show();
break;
case "Smallest first":
sets = dbManager.getSets("order by pieces asc");
Toast.makeText(getContext(),sets.get(0).getName(), Toast.LENGTH_SHORT).show();
break;
default:
}
adapter.notifyDataSetChanged();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {}
});
disclaimer = root.findViewById(R.id.disclaimer);
disclaimer.setMovementMethod(LinkMovementMethod.getInstance());
return root;
}
What I've noticed is that I can get refreshed recyclerView if I replace:
adapter.notifyDataSetChanged();
with
adapter = new MyRecyclerViewAdapter(getActivity(), sets, portrait);
recyclerView.setAdapter(adapter);
But that doesn't seem right. I should be able to refresh the existing adapter with new data instead of creating a brand new adapter, correct?
This is a classic issue faced by many developers frequently.
Quick Fix:
Replace
sets = dbManager.getSets("order by pieces desc");
with
sets.clear()
sets.addAll(dbManager.getSets("order by pieces desc"));
And same for Ascending Order also.
Explanation:
When you initialize the Adapter, you pass an Arraylist whose instance is stored by the Adapter. When you call notifyDataSetChanged(), Adapter reads the instance and refreshes the layout as per the new ArrayList. However, when you reinitialize the ArrayList with sets = dbManager.getSets("order by pieces desc");, the adapter loses the reference to the new list and is unable to refresh the layout. This can be fixed by keeping the instance the same and replacing the values which are done using clear() and addAll(list).
Feel free to ask for any doubts in comments and please mark this answer correct if I am able to solve your problem.
Inside your adapter class create method:
setData(ArrayList<LEGOSet> sets) { // new list here
this.sets = sets; // assing ArrayList from database to your list which is inside adapter class
notifyDataSetChanged();
}
and then just replace adapter.notifyDataSetChanged() with adapter.setData(sets)

Android Studio - New Item in List is not shown

In my App i have a ListView, if i add some new Items, the ListView does not shown the Items. The items will be shown if i close the app and go back in it.
So my new Items are saved in my Database, but the list will not be synchronized.
i followed a Tutorial on youtube, if he tries it, it works fine, but not in my app. i hope someone can help me to find my problem.
In my newItem_Activity i have an Add-Button with following Code:
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(todo.getName() == null){
Toast.makeText(ToDoCreateNew.this, "Please insert some value.", Toast.LENGTH_LONG).show();
return;
}
ToDoDatabaseHelper.getInstance(ToDoCreateNew.this).createTodo(todo);
finish();
}
});
My Database looks like this:
public ToDo createTodo(final ToDo todo) {
SQLiteDatabase database = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(NAME_COLUMN, todo.getName());
contentValues.put(DUEDATE_COLUMN, todo.getDueDate() == null ? null : todo.getDueDate().getTimeInMillis() / 1000);
contentValues.put(FAVORITE_COLUMN, todo.isFavorite() ? 1 : 0);
contentValues.put(DESCRIPTION_COLUMN, todo.getDescription());
contentValues.put(DUETIME_COLUMN, String.valueOf(todo.getDueTime() == null ? null : todo.getDueTime().getTime()));
long newID = database.insert(TABLE_NAME, null, contentValues);
database.close();
return readToDo(newID);
}
public List<ToDo> readAllToDos(){
List<ToDo> todos = new ArrayList<>();
SQLiteDatabase database = this.getReadableDatabase();
Cursor c = database.rawQuery("SELECT * FROM " + TABLE_NAME, null);
if (c.moveToFirst()){
do {
ToDo todo = readToDo(c.getLong(c.getColumnIndex(ID_COLUMN)));
if (todo != null){
todos.add(todo);
}
} while (c.moveToNext());
}
database.close();
return todos;
}
and this Code is on my Activity with my ListView:
List<ToDo> dataSource;
ToDoOverviewListAdapter adapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_to_do_overview);
lv = (ListView) findViewById(R.id.listToDo);
dataSource = ToDoDatabaseHelper.getInstance(this).readAllToDos();
adapter = new ToDoOverviewListAdapter(this, dataSource);
lv.setAdapter(new ToDoOverviewListAdapter(this, dataSource));
}
// Go to Activity to Add new Item - Add Button is in newItem_Activity
public void createToDo(){
startActivity(new Intent(ToDoOverview.this, ToDoCreateNew.class));
refreshListView();
}
private void refreshListView(){
dataSource.clear();
dataSource.addAll(ToDoDatabaseHelper.getInstance(this).readAllToDos());
adapter.notifyDataSetChanged();
}
Do one thing when you add lists in adapter , wrap it in a method and call that method in both onCreate and OnStart Method . So basically you have to add list in adapter two times On OnCreate method and OnStart method. So When you update the data and move back to your original activity it will trigger OnStart method and it will show updated data.

Change SQL query based on button action

I have a listview that displays all the items in my database. I am trying to create a button that will change the data displayed to only show items that match today's date.
What is the best way to change the query that is being run in the app based on a button push and update the listview?
I've played with setting a flag in the onclick() method paired with if-else statements that held the query call, but it did not seem to switch which was being called.
The flag is the boolean filterToday. set in the onClickListener of todayButton.
public class MainActivity extends AppCompatActivity {
public final static String KEY_EXTRA_CONTACT_ID = "KEY_EXTRA_CONTACT_ID";
private ListView listView;
DBHelper dbHelper;
boolean filterToday;
Cursor cursor;
String [] columns;
int [] widgets;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button addButton = (Button) findViewById(R.id.addNew);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddTaskActivity.class);
intent.putExtra(KEY_EXTRA_CONTACT_ID, 0);
startActivity(intent);
}
});
Button todayButton = (Button) findViewById(R.id.today);
todayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
filterToday = true;
}
});
dbHelper = new DBHelper(this);
if(filterToday == true){
Calendar cal = Calendar.getInstance();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String date = df.format(cal.getTime());
Toast.makeText(this,date,Toast.LENGTH_LONG).show();
cursor = dbHelper.getTodaysTasks(date);
}
else{
cursor = dbHelper.getAllTasks();
}
columns = new String[] {
DBHelper.TASK_COLUMN_NAME,
DBHelper.TASK_COLUMN_TYPE,
DBHelper.TASK_COLUMN_DATE
};
widgets = new int[] {
R.id.taskName,
R.id.taskType,
R.id.taskDate
};
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, R.layout.task_info,
cursor, columns, widgets, 0);
listView = (ListView)findViewById(R.id.listView1);
listView.setAdapter(cursorAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
Cursor itemCursor = (Cursor) MainActivity.this.listView.getItemAtPosition(position);
int taskID = itemCursor.getInt(itemCursor.getColumnIndex(DBHelper.TASK_COLUMN_ID));
Intent intent = new Intent(getApplicationContext(), AddTaskActivity.class);
intent.putExtra(KEY_EXTRA_CONTACT_ID, taskID);
startActivity(intent);
}
});
}
}
These are the two queries I am trying to switch between:
public Cursor getAllTasks() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery( "SELECT * FROM " + TASK_TABLE_NAME, null );
return res;
}
public Cursor getTodaysTasks(String date){
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("SELECT * FROM " + TASK_TABLE_NAME + " WHERE " +
TASK_COLUMN_DATE + " =?", new String[]{date});
return res;
}
OK so the first thing to notice is that your update filterToday = true; inside the onclick listener, the if(filterToday == true){...} outside doesn't know that. That part is only executed once in the oncreate()
If you'd like to perform that action I suggest a small change.. like below
Create a seperate function outside for the data loading
private void LoadMyData() {
if(filterToday == true){
Calendar cal = Calendar.getInstance();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String date = df.format(cal.getTime());
//you might need to update this line
//Toast.makeText(this,date,Toast.LENGTH_LONG).show();
//assume dbHelper is ready at this point
cursor = dbHelper.getTodaysTasks(date);
}
else{
cursor = dbHelper.getAllTasks();
}
}
Call this function inside onclick listner
filterToday = false;//initialize to false if necessary
todayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
filterToday = !filterToday ;//by doing it like this you can switch back and forth. add/check extra logic if necessary
LoadMyData();
}
});
LoadMyData(); //Call this outside in the oncreate to load the data initially
I'm not suggesting a code improvement here. Just changes to what you already have. Hope it helps.
There were two issues that I ran into, the first was comparing a string to to the SQL string[], which meant while the comparison was working, it did not behave as I expected. Once fixing this issue was updating the ListView object. This was handled by creating a new adapter and attaching it to ListView, which then updates itself.
Per this answer: Refresh Current Fragment (ListView Data) remaining in the same activity
The other option was to call notifyDataSetChanged() on the adapter, but this did not work well with the way I had my program set up.

Android ListFragment data not updating via SimpleCursorAdapter / LoaderManager / notifyChange()

I have a ListFragment that shows the names of all the shopping lists stored in my database table.
The problem is that when I add a new shopping list row to the table, the ListFragment on the UI is not automatically updated. (The change can only be seen if I close and restart the app.)
Firstly, this is the code that is executed in my DbContentProvider class when I add a shopping list:
`
// Insert the values into the table
id = db.insert(SHOPPING_LISTS_META_TABLE, null, values);
if (id > -1) {
// Construct and return the URI of the newly inserted row.
Uri insertedId = ContentUris.withAppendedId(CONTENT_URI_SHOPPING_LISTS_META, id);
// Notify any observers of the change in the data set.
Log.d(LOG_TAG, "................. notifyChange(\"" + insertedId + "\", null)");
getContext().getContentResolver().notifyChange(insertedId, null);
Log.d(LOG_TAG, "................. notifyChange() done");
return insertedId;
}
else {
return null;
}
`
...and here is the LogCat output for it...
10-28 12:29:41.133: D/SQLiteOpenHelper(19401): ................. notifyChange("content://org.example.myapp.DbContentProvider/shopping_lists_meta/12", null)
10-28 12:29:41.143: D/SQLiteOpenHelper(19401): ................. notifyChange() done
10-28 12:29:41.153: D/HomeActivity(19401): Shopping list, "My Test Shopping List" created: content://org.example.myapp.DbContentProvider/shopping_lists_meta/12
10-28 12:29:41.183: D/AbsListView(19401): unregisterIRListener() is called
10-28 12:29:41.193: E/ViewRootImpl(19401): sendUserActionEvent() mView == null
10-28 12:29:41.503: D/AbsListView(19401): unregisterIRListener() is called
In LogCat, there is no output at all from my ListFragment class when I add the new shopping list row. Here is my ListFragment class...
`
public class ShoppingListNamesListFragment extends ListFragment implements LoaderManager.LoaderCallbacks {
private final static String LOG_TAG = ShoppingListNamesListFragment.class.getSimpleName();
// This is the Adapter being used to display the list's data
public static SimpleCursorAdapter mAdapter;
// These are the Contacts rows that we will retrieve
static final String[] PROJECTION = {DbContentProvider.KEY_ID,
DbContentProvider.KEY_SHOPPING_LIST_NAME,
DbContentProvider.KEY_IS_SHOPPING_LIST_SELECTED};
// This is the select criteria
static final String SELECTION = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(LOG_TAG, "................. onCreate()");
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(LOG_TAG, "................. onActivityCreated()");
// For the cursor adapter, specify which columns go into which views
String[] fromColumns = {DbContentProvider.KEY_SHOPPING_LIST_NAME};
int[] toViews = {android.R.id.text1}; // The TextView in simple_list_item_1
// Create an empty adapter we will use to display the loaded data.
// We pass null for the cursor, then update it in onLoadFinished()
mAdapter = new SimpleCursorAdapter(this.getActivity(),
android.R.layout.simple_list_item_1, null,
fromColumns, toViews, 0);
setListAdapter(mAdapter);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(LOG_TAG, "................. onCreateView()");
return super.onCreateView(inflater, container, savedInstanceState);
}
// Called when a new Loader needs to be created
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Log.d(LOG_TAG, "................. onCreateLoader()");
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
return new CursorLoader(getActivity(), DbContentProvider.CONTENT_URI_SHOPPING_LISTS_META,
PROJECTION, SELECTION, null, null);
}
// Called when a previously created loader has finished loading
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
Log.d(LOG_TAG, "................. onLoaderFinished()");
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mAdapter.swapCursor(data);
}
// Called when a previously created loader is reset, making the data unavailable
#Override
public void onLoaderReset(Loader<Cursor> loader) {
Log.d(LOG_TAG, "................. onLoaderReset()");
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
mAdapter.swapCursor(null);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
makeToast("shopping list clicked: " + position);
Log.d(LOG_TAG, "shopping list clicked: " + position);
}
private void makeToast(String msg) {
Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();
}
}
NB - In my DbContentProvider class, I have...
public static final Uri CONTENT_URI_SHOPPING_LISTS_META = Uri.parse("content://org.example.myapp.DbContentProvider/shopping_lists_meta");
public static final String SHOPPING_LISTS_META_TABLE = "shopping_lists_meta";
I have based my code on this Android ListFragment / LoaderManager example. And none of the similar questions to this that I have found offer a solution that fixes my problem.
I am fairly new to Android, so it could be a simple mistake I've made. But, essentially, it seems to me that when notifyChange() is called in my DbContentProvider class, my ListFragment is not being notified (or there is some other error in this area). Can anyone help?
After spending hours and hours on this, I created a TestListActivity that hooked up to the native Contacts content provider - and that all worked/updated as it should, so I knew the issue was probably in my own content provider that I'd written.
I found the answer here. Turns out I had not called setNotificationUri(ContentResolver cr, Uri uri) on the cursor returned by the query() method of my content provider. (I'm sure this was never mentioned in the Reto Mauer book I was working from...) :/
Anyway, all sorted now! :)

Android AsyncTask making sure all data has been loaded

Hi I'm trying to create an Asynctask that runs two functions and when they are done loading it then fills the UI with the data. at the moment for somereason it only fills the UI with data from one of the Functions and its which ever of the functions finishes loading first.
For Example
i have two functions LoadNewsFeed() and LoadResultsFeed() at the moment loadResultsFeed() shows the data and not anything from loadNews() however if i comment out LoadResultsFeed() the data from loadNews fills The UI but not from loadResultsFeed
is there a way i could set it to if that one is finished loading, load the other than perform the FillData() function?
heres what i have so far
public class PostTask extends AsyncTask {
#Override
protected Boolean doInBackground(Void... params) {
boolean result = false;
loadNewsFeed();
publishProgress("method1");
loadResultsFeed();
publishProgress("method2");
return result;
}
protected void onProgressUpdate(String... progress) {
StringBuilder str = new StringBuilder();
for (int i = 1; i < progress.length; i++) {
str.append(progress[i] + " ");
}
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Log.v("BGThread", "begin fillin data");
FillData();
}
}
heres my FillData() Function
public void FillData(){
if (ChosenMethod.equals("Team")) {
arrayAdapter = new ArrayAdapter<String>(this, R.layout.single_item, newsList);
String[] mStrings = (String[]) imageList.toArray(new String[imageList.size()]);
String[] news = (String[]) newsList3.toArray(new String[newsList3.size()]);
arrayAdapter3 = new LazyAdapter(this, mStrings, news);
ListView list = getListView();
list.setTextFilterEnabled(true);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE );
View header = inflater.inflate( R.layout.homeheader, list, false);
View header2 = inflater.inflate( R.layout.homeheader2, list, false);
View header3 = inflater.inflate( R.layout.homeheader3, list, false);
//setListAdapter (arrayAdapter);
resultsView = LayoutInflater.from(getBaseContext()).inflate(R.layout.resultscell,
null);
TextView homeTeam = (TextView) resultsView.findViewById(R.id.HomeTeam);
homeTeam.setText(HomeTeam);
TextView awayTeam = (TextView) resultsView.findViewById(R.id.AwayTeam);
awayTeam.setText(AwayTeam);
TextView homeScore = (TextView) resultsView.findViewById(R.id.HomeScore);
homeScore.setText(HomeScore);
TextView awayScore = (TextView) resultsView.findViewById(R.id.AwayScore);
awayScore.setText(AwayScore);
TextView attendance = (TextView) resultsView.findViewById(R.id.Attendence);
attendance.setText("Att:" + Attendance);
TextView division = (TextView) resultsView.findViewById(R.id.Division);
division.setText(Division);
Log.v("BGThread", "Filled results");
adapter = new MergeAdapter();
adapter.addView(header);
adapter.addAdapter(arrayAdapter);
adapter.addView(header2);
adapter.addView(resultsView);
adapter.addView(header3);
adapter.addAdapter(arrayAdapter3);
setListAdapter(adapter);
Log.v("BGThread", "Filled Merge Adapter Team");
} else {
arrayAdapter = new ArrayAdapter<String>(this, R.layout.single_item, newsList);
arrayAdapter2 = new ArrayAdapter<String>(this, R.layout.single_item, newsList2);
//arrayAdapter3 = new ArrayAdapter(this, R.layout.complex_item, newsList3);
String[] mStrings = (String[]) imageList.toArray(new String[imageList.size()]);
String[] news = (String[]) newsList3.toArray(new String[newsList3.size()]);
arrayAdapter3 = new LazyAdapter(this, mStrings, news);
ListView list = getListView();
list.setTextFilterEnabled(true);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE );
View header3 = inflater.inflate( R.layout.homeheader3, list, false);
//setListAdapter (arrayAdapter);
adapter = new MergeAdapter();
adapter.addView(header3);
adapter.addAdapter(arrayAdapter3);
setListAdapter(adapter);
Log.v("BGThread", "Filled Merge Adapter League");
}
}
A quick and easy way is to add a boolean field to your class which is initially true:
private boolean bothFeedsLoaded = true;
Then toggle it's value in onPostExecute:
bothFeedsLoaded = !bothFieldsLoaded;
In your FillData method:
if (!bothFeedsLoaded){return;}
As bothFeedsLoaded is initially true, then the first callback to onPostExecute (after whichever feed loads first) will change it to false. Your fillData method will therefore return without doing anything. When the second feed finished loading, onPostEexcute will change it back to true and your fillData will do it's thing.
Alternatively (and perhaps a little easier to read in 6 months time) is to use an integer:
private int feedsLoaded = 0;
.....
feedsLoaded ++;
.....
if (feedsLoaded != 2) {return;}
There are better ways, e.g. creating separate classes for each loading task then synchronising both with a semaphore in their respective onPostExecute callbacks, but this should work.
If using AsyncTask is not crucial, i would suggest the use of Thread class along with Handler,
You can use join, the class which has those two methods, let it implement Runnable interface, then you can make an object of the class and pass it to the Thread constructor. Then use join on the thread, that means until and unless the thread dies it wont execute the below line, and just after the join, use the lines to place the data on the UI.
You can also you CountDownLatch from java.util.Concurrent package, which will wait for the specific work to be done, and then execute further.

Categories

Resources