I made simple Client server to android.
I have problem when I send an object from server to the client.
The object is received ok and when I check the log, it shows me the the object was sent successfully.
The problem occurs when I'm trying to get this object and put it in my ListView adapter.
The adapter works, I checked it with a random ArrayList I created.
My issue is when I'm trying to to put the values of AsyncTask in my adapter.
public class RestaurantListFragment extends Fragment {
private ArrayList<Resturant> res = new ArrayList<>();
private ListAdapter adapter;
private Firebase restRef = new Firebase("https://restmeup.firebaseio.com/restaurants");
private Client mClient;
// private connectTask t = (connectTask)new connectTask().execute();
public RestaurantListFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new connectTask().execute();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// new connectTask(getView()).execute();
final View rootView = inflater.inflate(R.layout.fragment_two, container, false);
ListView restaurantList = (ListView) rootView.findViewById(R.id.list);
adapter = new ListAdapter(getContext(), res, getActivity());
restaurantList.setAdapter(adapter);
// connectTask t = (connectTask)new connectTask().execute();
if (mClient != null) {
mClient.sendMessage("bar");
}
SqlQueriesConverter sql = new SqlQueriesConverter();
sql.getResurantsListQuery("bar");
// sql.getUserFavoritesResturants(accessToken.getUserId());
mClient.sendMessage(sql.getQuery());
// t.setArray(res);
mClient.sendMessage("/quit");
mClient.stopClient();
final EditText searchText = (EditText)rootView.findViewById(R.id.searchListView);
searchText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
System.out.println("Before---------");
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String text = searchText.getText().toString().toLowerCase(Locale.getDefault());
adapter.filter(text);
adapter.notifyDataSetChanged();
System.out.println("array: " + res.toString());
}
#Override
public void afterTextChanged(Editable s) {
System.out.println("After---------");
}
});
// Inflate the layout for this fragment
return rootView;
}
public class connectTask extends AsyncTask<ArrayList<?>,ArrayList<?>,Client> {
// private Client mClient;
private ArrayList<?> arrayList = new ArrayList<>();
#Override
protected Client doInBackground(ArrayList<?>... message) {
//we create a Client object and
mClient = new Client(new Client.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(ArrayList<?> message) {
//this method calls the onProgressUpdate
// publishProgress(message);
onProgressUpdate(message);
}
});
mClient.run();
return null;
}
// #Override
protected void onProgressUpdate(ArrayList<?>... values) {
super.onProgressUpdate(values);
ArrayList<?> arr2;
if (values[0].get(0) instanceof Resturant){
Log.d("step 1", "1");
if (((ArrayList<?>)values[0]).get(0)instanceof Resturant) {
// arr2 = (ArrayList<Resturant>) values[0];
res = (ArrayList<Resturant>) values[0];
adapter.notifyDataSetChanged();
Log.d("array",res.toString());
}
}
if (values[0].get(0)instanceof Review){
arr2 = (ArrayList<Review>) values[0];
}
if (values[0].get(0)instanceof UserFavorites){
arr2 = (ArrayList<Review>) values[0];
Log.d("step 2", "2");
}
}
}
}
There are two things you need to change to use the AsyncTask as you intend. The first change you need is to return the ArrayList you get from your mClient in the doInBackground method. This is a bit troublesome because it looks like the Client is already running asynchronously since you pass a callback to get the result (this is the Client.OnMessageReceived anonymous class you have there). The second change would be to implement onPostExecute on your AsyncTask since that is where the results from doInBackground are sent. You'd add the result sent from doInBackground to your adapter in there.
In any case, since it looks like Client is already performing the work asynchronously, you shouldn't need to use an AsyncTask at all. Just implement the logic to add the results to your adapter in the Client.OnMessageReceived callback.
Just get the code you already have in onProgressUpdate and throw it inside messageReceived. Something like this:
mClient = new Client(new Client.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(ArrayList<?> values) {
if (values[0].get(0) instanceof Resturant){
Log.d("step 1", "1");
if (((ArrayList<?>)values[0]).get(0)instanceof Resturant) {
res = (ArrayList<Resturant>) values[0];
adapter.notifyDataSetChanged();
Log.d("array",res.toString());
}
}
}
});
Related
Some background information:
I am using a Activity>ParentFragment(Holds ViewPager)>Child fragments.
Child Fragments are added dynamically with add, remove buttons.
I am using MVP architecture
Actual Problem:
In child fragment, we have listview that populates using an asynctaskloader via a presenter.
Child Fragment:
//Initialize Views
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_search_view_child, container, false);
.......
mSearchViewPresenter= new SearchViewPresenter(
getActivity(),
new GoogleSuggestLoader(getContext()),
getActivity().getLoaderManager(),
this, id
);
SearchList list=new SearchList();
//requestList from presenter
searchListAdapter =new SearchViewListAdapter(getActivity(), list, this);
listView.setAdapter(searchListAdapter);
......
return root;
}
#Override
public void onResume(){
super.onResume();
mSearchViewPresenter.start();
searchBar.addTextChangedListener(textWatcher);
}
In the presenter class we have:
public SearchViewPresenter(#NonNull Context context, #NonNull GoogleSuggestLoader googleloader,#NonNull LoaderManager loaderManager,
#NonNull SearchViewContract.View tasksView, #NonNull String id) {
// mLoader = checkNotNull(loader, "loader cannot be null!");
mLoaderManager = checkNotNull(loaderManager, "loader manager cannot be null");
// mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null");
mSearchView = checkNotNull(tasksView, "tasksView cannot be null!");
mSearchView.setPresenter(this);
searchList=new SearchList();
this.googleLoader=googleloader;
this.context=context;
this.id=loaderID;
// this.id=Integer.parseInt(id);
}
#Override
public void start() {
Log.d("start>initloader","log");
mLoaderManager.restartLoader(1, null, this);
}
//TODO implement these when you are ready to use loader to cache local browsing history
#Override
public android.content.Loader<List<String>> onCreateLoader(int i, Bundle bundle) {
int loaderid=googleLoader.getId();
Log.d("Loader: ", "created");
googleLoader=new GoogleSuggestLoader(context);
googleLoader.setUrl("");
googleLoader.setUrl(mSearchView.provideTextQuery());
return googleLoader;
}
#Override
public void onLoadFinished(android.content.Loader<List<String>> loader, List<String> data) {
Log.d("Loader: ", "loadFinished");
searchList.clear();
for (int i = 0; i < data.size(); ++i) {
searchList.addListItem(data.get(i), null, LIST_TYPE_SEARCH, android.R.drawable.btn_plus);
Log.d("data Entry: ",i+ " is: "+searchList.getText(i));
}
mSearchView.updateSearchList(searchList);
}
#Override
public void onLoaderReset(android.content.Loader<List<String>> loader) {
}
Also we have this code in the presenter that is triggered by a edittext box on the fragment view being edited.
#Override
public void notifyTextEntry() {
//DETERMINE HOW TO GIVE LIST HERE
// Dummy List
Log.d("notifyTextEntry","log");
if(googleLoader==null)googleLoader=new GoogleSuggestLoader(context);
googleLoader.setUrl(mSearchView.provideTextQuery());
// mLoaderManager.getLoader(id).abandon();
mLoaderManager.getLoader(1).forceLoad();
mLoaderManager.getLoader(1).onContentChanged();
Log.d("length ", searchList.length().toString());
// googleLoader.onContentChanged();
}
Lastly we have the loader here:
public class GoogleSuggestLoader extends AsyncTaskLoader<List<String>>{
/** Query URL */
private String mUrl;
private static final String BASE_URL="https://suggestqueries.google.com/complete/search?client=firefox&oe=utf-8&q=";
private List<String> suggestions =new ArrayList<>();
public GoogleSuggestLoader(Context context) {
super(context);
this.mUrl=BASE_URL;
}
public void setUrl(String mUrl){
this.mUrl=BASE_URL+mUrl;
};
#Override
protected void onStartLoading() {forceLoad(); }
#Override
public List<String> loadInBackground() {
if (mUrl == null) {
return null;
}
try {
suggestions = new ArrayList<>();
Log.d("notifyinsideLoader","log");
String result=GoogleSuggestParser.parseTemp(mUrl);
if(result!=null) {
JSONArray json = new JSONArray(result);
if (json != null) {
JSONArray inner=new JSONArray((json.getString(1)));
if(inner!=null){
for (int i = 0; i < inner.length(); ++i) {
//only show 3 results
if(i==3)break;
Log.d("notifyinsideLoader",inner.getString(i));
suggestions.add(inner.getString(i));
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return suggestions;
}
}
So the problem:
The code loads the data fine to the listview on the fragment. When orientation changes loader is not calling onLoadFinished. I have tested the loader and it is processing the data fine.
I have already tried forceload and onContentChanged in the presenter to no avail.
If you need anymore info or if I should just use something else like RxJava let me know. But I would really like to get this working.
Before you ask I have seen similar problems like: AsyncTaskLoader: onLoadFinished not called after orientation change however I am using the same id so this problem should not exist.
The answer was on this page AsyncTaskLoader doesn't call onLoadFinished
but details were not given as to how to move to this.
So let me explain here for anyone else with this problem in future.
Support library is meant for fragments. So the class that is in charge of callbacks has to be importing AND implementing the correct methods from the support library. Same as if you are using MVP your presenter must extend from support loadermanager.
i.e: import android.support.v4.app.LoaderManager; Then implement correct callbacks.
Like
#Override
public android.support.v4.content.Loader<List<String>> onCreateLoader(int i, Bundle bundle) {
...
return new loader
}
and
#Override
public void onLoadFinished(android.support.v4.content.Loader<List<String>> loader, List<String> data) {
//do something here to your UI with data
}
Secondly: The loader itself must be extending from support asynctaskloader.
i.e: import android.support.v4.content.AsyncTaskLoader;
I have a ListView which I populate with data from DataStore or from my local database.
I am checking some condition that will determine whether I will fetch data from the DataStore or database. When I fetch from the database the ListView automatically refreshes itself, but when I fetch from the DataStore it does not. I then have to click my TextView, which is below ListView, and when I click it the soft keyboard appears and then my ListView is populated with data from DataStore.
My activity that has the ListView:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_xyz);
list_View = (ListView) findViewById(R.id.data_listView);
list_View.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
list_View.setMultiChoiceModeListener(new Selector());
adapter = new MyAdapter(context,Long.valueOf(id),isOnline());
list_View.setAdapter(adapter);
list_View.setSelection(adapter.getCount() - 1);
adapter.registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged() {
super.onChanged();
list_View.setSelection(adapter.getCount() - 1);
}
LoadDataTask ldt = new LoadDataTask();
ldt.execute("123456789");
}
private void loadDataFromDataStore(final Long contactId){
final ArrayList<Data> data = new ArrayList<>();;
d("loadingdataFromDatasore");
GetDataTask task = new GetDataTask(new ApiTask.ResultListener() {
#Override
public void successHook(Object o) {
if (o instanceof GetDataResponse) {
GetDataResponse res = (GetDataResponse) o;
if (res.getData() != null && res.getData().getItems() != null) {
for (ListDataItem i : res.getData().getItems()) {
Data dp = new Data(i.getPosition(), i.getMessage(), i.getDateCreated(),i.getMessageId(),1);
adapter.addFromOtherThread(dp);
}
}
d("Messages loaded from server: " + adapter.getCount());
}
}
}
public class LoadDataTask extends AsyncTask<String,String,Void> {
#Override
protected Void doInBackground(String... params){
if(isOnline && isFirstTime){
loadDataFromDataStore(Long.valueOf(params[0]));
}else{
//load from database
}
return null;
}
#Override
protected void onPostExecute(Void v){
adapter.notifyDataSetChanged();
}
}
My adapter class that extends BaseAdapter (I have removed unnecessary code for this question):
public class DataAdapter extends BaseAdapter {
private ArrayList<Data>data_list;
public DataAdapter(){
data_list = new ArrayList<>();
}
public void addFromOtherThread(Data object) {
data_list.add(object);
}
What am I missing that is making listview not to automatically refresh itself even after calling notifyDatasetChanged()?
change :
#Override
protected void onPostExecute(Void v){
adapter.notifyDataSetChanged();
}
}
to:
#Override
protected void onPostExecute(Void v){
adapter.notifyDataSetChanged();
list_View.setAdapter(adapter);
}
}
Let me know if more clarification is required by commenting below.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_xyz);
list_View = (ListView) findViewById(R.id.data_listView);
list_View.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
list_View.setMultiChoiceModeListener(new Selector());
adapter = new MyAdapter(context,Long.valueOf(id),isOnline());
list_View.setAdapter(adapter);
list_View.setSelection(adapter.getCount() - 1);
adapter.registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged() {
super.onChanged();
list_View.setSelection(adapter.getCount() - 1);
}
loadDataFromDataStore("123456789")
}
private void loadDataFromDataStore(final Long contactId){
final ArrayList<Data> data = new ArrayList<>();;
d("loadingdataFromDatasore");
new GetDataTask(new ApiTask.ResultListener() {
#Override
public void successHook(Object o) {
if (o instanceof GetDataResponse) {
GetDataResponse res = (GetDataResponse) o;
if (res.getData() != null && res.getData().getItems() != null) {
for (ListDataItem i : res.getData().getItems()) {
Data dp = new Data(i.getPosition(), i.getMessage(), i.getDateCreated(),i.getMessageId(),1);
adapter.addFromOtherThread(dp);
}
}
d("Messages loaded from server: " + adapter.getCount());
adapter.notifyDatasetChanges();
}
}
}.execute();
}
GetDataTask should work on background internally you don't need to starts a AsyncTask from here.
If you want to use AsyncTask then your AsyncTask should wait for the result from GetDataTask which it is not doing in your code implementation.
I don't know which kind of framework you are using to making api call but your implementation seems to look wrong.
I have write the code on assumption bases if your GetDataTask is a AsyncTask or some background processor it will work perfectly.
My app requires to parse a XML file when the activity is launched. So, I use an Asynctask to parse the XML.
After parsing the XML file, I get the count of number of test-cases in the XML in doInBackground() method, and I use the variable alTestCaseList to keep this count.
Later in onPostExecute() method, I set the ArrayAdapter and register the click listener for the list.
However, when I click any testcase from the list, I'm supposed to parse the test-case entries from the XML again.
So I believe for this I'll have to use an AsyncTask again. So do I start another AsyncTask for onPostExecute() method of first AsyncTask?
Is there any other neat way of doing this?
I tried to put setOnItemClickListener() in onCreate() method, but it resulted in fatal exception with the message: "setOnItemClickListener(android.widget.AdapterView$OnItemClickListener) on a null object reference"........
Kindly give your suggestion.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testcases);
xmlHelp = new XmlHelper();
ConfigParser confParser = new ConfigParser();
confParser.execute();
}
private class ConfigParser extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
alTestCaseList = xmlHelp.getNumberOfNodes();
return null;
}
#Override
protected void onPostExecute(Void v) {
testCasesListView = (ListView) findViewById(R.id.lstTestCases);
arrayAdapter = new ArrayAdapter(TestCasesActivity.this, android.R.layout.simple_list_item_1, alTestCaseList);
testCasesListView.setAdapter(arrayAdapter);
testCasesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long arg3) {
String value = (String) adapter.getItemAtPosition(position);
Log.d("QcTool", "Selected: " + value);
}
});
}
}
Here is my take on the solution. Pass your data as an argument to the task and notify the adapter when you get the list.
See the comments for further explanation. Note that this approach does not handle issues that AsyncTask's typically come with is situations such as configuration changes.
You can then create another ParseXmlTask class which can be called in your OnItemClicked method
private ListView testCasesListView;
private ArrayAdapter arrayAdapter;
private List<String> testCasesList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testcases);
//Init the list - it's empty but your task will fill it.
testCasesList = new ArrayList<>();
//Init your listView
testCasesListView = (ListView) findViewById(R.id.lstTestCases);
//Add adapter to the listView
arrayAdapter = new ArrayAdapter(TestCasesActivity.this, android.R.layout.simple_list_item_1, alTestCaseList);
//Add your click event
testCasesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long arg3) {
//When clicked, do something awesome
String value = (String) adapter.getItemAtPosition(position);
Log.d("QcTool", "Selected: " + value);
//Create and start parseXmlTask here
}
});
xmlHelp = new XmlHelper();
//Pass in your callback as an argument
ConfigParserTask confParser = new ConfigParserTask(new OnConfigParserTaskCompleted(){
public void onConfigParserTaskCompleted(List<String> result){
//Simply refresh the list
testCasesList.clear();
testCasesList.addAll(result);
//Let the adapter know that the list has changed
//Then update the list view
arrayAdapter.notifyDataSetChanged();
}
});
confParser.execute(xmlHelp);
}
//It's better to pass in the info to the task as arguments than it is to rely on
//field variables
private class ConfigParserTask extends AsyncTask<XmlHelper, Void, List<String>> {
private OnConfigParserTaskCompleted listener;
public ConfigParser(OnConfigParserTaskCompleted listener){
this.listener = listener;
}
#Override
protected Void doInBackground(XmlHelper... params) {
//Do what you need to in the background
//Get your nodes then return it here
List<String> nodes = params[0].getNumberOfNodes();
return nodes;
}
#Override
protected void onPostExecute(List<String> result) {
//pass the result to the callback
listener.onConfigParserTaskCompleted(result);
}
}
//Callback to let your activity/fragment know when
//the task is complete
public interface OnConfigParserTaskCompleted{
public void onConfigParserTaskCompleted(List<String> result);
}
You can do something like this using AsyncTasks
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testcases);
testCasesListView = (ListView) findViewById(R.id.lstTestCases);
testCasesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long arg3) {
String value = (String) adapter.getItemAtPosition(position);
Log.d("QcTool", "Selected: " + value);
ParserNodeTask nodeTask = new ParserNodeTask();
nodeTask.execute(value);
}
});
xmlHelp = new XmlHelper();
ParserNumberOfNodesTask numberOfNodesTask = new ParserNumberOfNodesTask();
numberOfNodesTask.execute();
}
private class ParserNumberOfNodesTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
alTestCaseList = xmlHelp.getNumberOfNodes();
return null;
}
#Override
protected void onPostExecute(Void v) {
arrayAdapter = new ArrayAdapter(TestCasesActivity.this, android.R.layout.simple_list_item_1, alTestCaseList);
testCasesListView.setAdapter(arrayAdapter);
}
}
private class ParserNodeTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(String... params) {
String value = params[0];
//TODO : parse the selected node
}
#Override
protected void onPostExecute(Void v) {
//TODO: dunno what you need to do later
}
}
Though AsyncTasks are not ideal for this for many reasons (but easier to implement). You should maybe take a look on to Loaders or Services (i.e https://stackoverflow.com/a/6957909/665823)
I have a fragment activity and want to get data from my php script. I need this data to draw my ui effectively. My problem is my UI/fragment draws before i get data back, im not sure why as i fire it as early as i can in onCreate'. I put a dialog into pre and post to effectively freeze UI while data is retreived in background but....I dont see this happening, i think im too late in calling itas when the dialog appears during debug it shows ontop of a drawn screen which is baffling to me.
I have an alternative solution which is to fire the asyncTask in calling activity (previous activity) and pass result in bundle but i don't like this solution as its rigid and may cause issues with screen rotation.
I have been stuck on this for ages, can anybody tell me specifically where to put my async execute - the dialog should effectively make it a sync process. I have placed my asynctask everywhere i think possible/sensible and no luck.
In below i have the execute in the oncreate(). Note the execute doesnt d anything but update a test string which is "no change" beforehand, and "changed" in the postexecute so i can see what state its in at various points in code. It doesnt change before i draw my screen.
public class StaggeredGridActivityFragment extends FragmentActivity {
String test ="not changed";
private TilesAdapter mAdapter;
private ArrayList<String> mData;
private StaggeredGridView mGridView;
private static final String TAG = "StaggeredGridActivityFragment";
#Override
protected void onCreate(Bundle savedInstanceState) {
try
{
// Loading tile data in Background Thread
new GetLoginTiles().execute();
}
catch (Exception e)
{
e.printStackTrace();
}
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //remove title bar
final FragmentManager fm = getSupportFragmentManager();
// Create the list fragment and add it as our sole content.
if (fm.findFragmentById(android.R.id.content) == null) {
final StaggeredGridFragment fragment = new StaggeredGridFragment();
fm.beginTransaction().add(android.R.id.content, fragment).commit();
}
Intent i=getIntent();
Bundle extras = i.getExtras();
String tmp = extras.getString("myKey");
}
private class StaggeredGridFragment extends Fragment implements AbsListView.OnScrollListener, AbsListView.OnItemClickListener {
//private StaggeredGridView mGridView;
private boolean mHasRequestedMore;
// private TilesAdapter mAdapter;
//private ArrayList<String> mData;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_sgv, container, false);
}
#Override
public void onActivityCreated(final Bundle savedInstanceState) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
//Encapsulate all within a post cereate from a async task or call a blocking http call
super.onActivityCreated(savedInstanceState);
mGridView = (StaggeredGridView) getView().findViewById(R.id.grid_view);
if (savedInstanceState == null) {
final LayoutInflater layoutInflater = getActivity().getLayoutInflater();
View header = layoutInflater.inflate(R.layout.list_item_header_footer, null);
mGridView.addHeaderView(header);
}
if (mAdapter == null) {
mAdapter = new TilesAdapter(getActivity(), R.id.summary1_value);
}
if (mData == null) {
mData = ActivityTileData.getLoginTileDataArray(getActivity());
}
for (String data : mData) {
mAdapter.add(data); //Add each mData TileAdapter element to an mAdapter where it will be further broken down and used by the TileAdapter
}
mGridView.setAdapter(mAdapter);
mGridView.setOnScrollListener(this);
mGridView.setOnItemClickListener(this);
}
#SuppressLint("LongLogTag")
#Override
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
Log.d(TAG, "onScrollStateChanged:" + scrollState);
}
#SuppressLint("LongLogTag")
#Override
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount, final int totalItemCount) {
Log.d(TAG, "onScroll firstVisibleItem:" + firstVisibleItem +
" visibleItemCount:" + visibleItemCount +
" totalItemCount:" + totalItemCount);
// our handling
if (!mHasRequestedMore) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if (lastInScreen >= totalItemCount) {
Log.d(TAG, "onScroll lastInScreen - so load more");
mHasRequestedMore = true;
onLoadMoreItems();
}
}
}
//Loads all of the objects from the getLoginTileData() if called
private void onLoadMoreItems() {
while(mAdapter.getCount()<mData.size()) {
//final ArrayList<String> sampleData = SampleData.generateSampleData();
final ArrayList<String> loginTileData = ActivityTileData.getLoginTileDataArray(getActivity());
for (String data : loginTileData) {
mAdapter.add(data.toString());
}
// stash all the data in our backing store
mData.addAll(loginTileData);
// notify the adapter that we can update now
mAdapter.notifyDataSetChanged();
mHasRequestedMore = false;
}
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Toast.makeText(getActivity(), "Item Clicked: " + position, Toast.LENGTH_SHORT).show();
}
}
// Progress Dialog
private ProgressDialog qDialog;
// JSON parser class
JSONParser jParser = new JSONParser();
String url_login ="http://xxx/xxx.php";
/**
* Background Async Task to Load all images by making HTTP Request
* */
class GetLoginTiles extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
qDialog = new ProgressDialog(StaggeredGridActivityFragment.this);
qDialog.setMessage("Please wait...");
qDialog.setIndeterminate(false);
qDialog.setCancelable(false);
qDialog.show();
}
#Override
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject jsonLogin = jParser.makeHttpRequest(url_login, "GET", params);
test=jsonLogin.toString();
return jsonLogin.toString();
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String jsonString) {
// dismiss the dialog after getting all questions
qDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into imagebuttons
* */
test="local test has changed";
}
});
}
}
}
I have an alternative solution which is to fire the asyncTask in calling activity (previous activity) and pass result in bundle but i don't like this solution as its rigid and may cause issues with screen rotation.
this is a good way to do it
override onSaveInstanceState to save the extras between rotations
also see here for more details
edit: it seems you are trying to change the text using
test="local test has changed";
whaat you need to do is pass the activity to the asynctask then
VIEWTYPEHERE button= ( VIEWTYPEHERE) activity.findViewById(R.id.YOUR_VIEW"S_ID_HERE);
button.setText("");
a couple of notes
on post execute runs on ui thread you don't need a new runnable
also you forgot to call .run() on it
I have two major classes in my project. The first is for creating the connection between the client and the server. The second is for switching between activities.
first:
public class MyActivity extends Activity{
private ListView mList;
private ArrayList<String> arrayList;
private MyCustomAdapter mAdapter;
public TCPClient mTcpClient;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
boolean flag = getIntent().getBooleanExtra("flag",false);
arrayList = new ArrayList<String>();
final EditText editText = (EditText) findViewById(R.id.editText);
Button send = (Button)findViewById(R.id.send_button);
Button menu = (Button)findViewById(R.id.button1);
if (flag == true)
{
//relate the listView from java to the one created in xml
mList = (ListView)findViewById(R.id.list);
mAdapter = new MyCustomAdapter(this, arrayList);
mList.setAdapter(mAdapter);
new connectTask().execute("");
Intent myIntent = new Intent(MyActivity.this,Menu.class);
startActivity(myIntent);
}
send.setOnClickListener(new View.OnClickListener() {
// #Override
public void onClick(View view) {
String message = editText.getText().toString();
//clean the listView to 1 item
if (message.equals("clean"))
{
arrayList.removeAll(arrayList);
mList.removeAllViewsInLayout();
}
//add the text in the arrayList
arrayList.add("c: " + message);
//sends the message to the server
if (mTcpClient != null) {
mTcpClient.sendMessage(message);
}
//refresh the list
mAdapter.notifyDataSetChanged();
editText.setText("");
}
});
//change Activity to live screen mode (live)
menu.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent myIntent = new Intent(MyActivity.this, Menu.class);
startActivity(myIntent);
}
});
}
public class connectTask extends AsyncTask<String,String,TCPClient> {
#Override
protected TCPClient doInBackground(String... message) {
//we create a TCPClient object and
mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
// #Override
//print the message as an Item
public void messageReceived(String message) {
//this method calls the onProgressUpdate
publishProgress(message);
}
});
mTcpClient.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
//in the arrayList we add the messaged received from server
arrayList.add(values[0]);
// notify the adapter that the data set has changed. This means that new message received
// from server was added to the list
mAdapter.notifyDataSetChanged();
}
}
}
the object TCPClient mTcpClient is the major factor in my app. I use it communicate with the server. In addition, even if I switch between activities it is still running properly so I still get info from server even though I am not in that activity.
second:
public class Menu extends Activity
{
public MyActivity myActivity;
public TCPClient mtcp;
protected void onCreate(Bundle savedInstanceState, MyActivity myActivity)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
ImageView action = (ImageView) findViewById(R.id.imageView1);
action.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event)
{
// here I would like to use mTcpClient object mentioned in the first class
return false;
}
});
}
Basically what I need is a help on how to create in the second class reference to the object mTcpClient that is described in the first class.
You are doing it wrong. If you want to use TcpClient class regardless of context it should NOT be related to first Activity. What you should do is to use singleton pattern:
class TcpClient {
protected static TcpClient mInstance = null;
public TcpClient() {
// your init code...
}
public static TcpClient getInstance() {
if( mInstance == null ) {
mInstance = new TcpClient();
}
return mInstance;
}
...
}
and then, whenever you want to use TcpClient you just do:
TcpClient client = TcpClient.getInstance();