RecyclerView Pagination not maintaining Scroll Position - android

I am a newbie in android and I've been working around pagination with recyclercview. I am receiving my data from a server(running php) and returning it in a JSON format which brings the data in bunches like 1-10, 11-20... so on. I call notifyDataSetChanged with this. But the problem is recyclerview scrolls back to the top when retrieving more data instead of retaining the current position. How do I go about this?
When scrollbar gets to the bottom, it triggers the asynctask
AsynTask:
public class LoadRecharge extends AsyncTask<String, String, String> {
private boolean socketTimeout = false;
Context context;
public static final String TAG = "custom_message";
public AsyncResponse delegate = null;
private String server_url = "https://blockgator.com/mobile/endless.php";
public LoadRecharge(Context ctxt, AsyncResponse asyncResponse) {
delegate = asyncResponse;
context = ctxt;
}
#Override
protected String doInBackground(String... params) {
if (connectGoogle()) {
String post_data = "";
try {
URL url = new URL(server_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
post_data = URLEncoder.encode("page", "UTF-8") + "=" + URLEncoder.encode(params[0], "UTF-8");
bufferedWriter.write(post_data);
bufferedWriter.flush();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
return result;
} catch (IOException e) {
Log.e(TAG, "error: " + e.getMessage());
}
} else {
this.socketTimeout = true;
}
return null;
}
#Override
protected void onPreExecute() {
arr.add(null);
scrollAdapter.notifyItemInserted(arr.size() - 1);
}
#Override
protected void onPostExecute(String result) {
arr.remove(arr.size() - 1);
scrollAdapter.notifyItemRemoved(arr.size());
if (this.socketTimeout) {
Toast.makeText(context, "unable to connect to server", Toast.LENGTH_SHORT).show();
} else {
delegate.processFinish(result);
}
}
public boolean connectGoogle() {
try {
HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
urlc.setConnectTimeout(3000);
urlc.connect();
return (urlc.getResponseCode() == 200);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
#Override
public void processFinish(String output) {
try {
JSONObject jsonObject = new JSONObject(output);
if (jsonObject.get("status").toString().equals("success")) {
JSONArray jsonarr = jsonObject.getJSONArray("data");
String columns[] = {"id", "bill_amount", "bill_price", "variation"};
for (int i = 0; i < jsonarr.length(); i++) {
ArrayList<String> temp = new ArrayList<>();
for (String column : columns) {
temp.add(jsonarr.getJSONObject(i).getString(column));
}
arr.add(temp);
setAdapter(arr);
}
} else if (jsonObject.get("status").toString().equals("end")) {
total = "end";
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(this, "exception from json", Toast.LENGTH_LONG).show();
} catch (NullPointerException e) {
Toast.makeText(this, "Unable to connect to server...", Toast.LENGTH_LONG).show();
Toast.makeText(this, "Null from json", Toast.LENGTH_LONG).show();
}
}
public void setAdapter(ArrayList<ArrayList<String>> arr) {
recycler.setAdapter(scrollAdapter);
scrollAdapter.notifyDataSetChanged();
scrollAdapter.setLoading();
scrollAdapter.setOnItemClickListener(this);
scrollAdapter.setOnLoadMoreListener(this);
}

Remove this line recycler.setAdapter(scrollAdapter); You need to set your adapter just once either in Activity's onCreate method or Fragment's onCreateView method.

In setAdapter() you dont need to do recycler.setAdapter(scrollAdapter); again, just do it at the beginning
I do something similar, but reversed, working as chat
messages.addAll(0, oldMessages);
mAdapter.notifyItemRangeInserted(0, oldMessages.size());
mAdapter.notifyItemChanged(oldMessages.size());
mAdapter.setLoaded();
Im adding the old messages of the char to the messages.
Then notifing the adapter I have updated the source
I uses the 0 to put at the beginning

Related

Android - Call Thread synchronized on UI thread

I try to create synchronized threads, but I always get the following error: android.os.NetworkOnMainThreadException.
I've read more posts, but they don't work for me.
Below I write the code blocks that do not work for me:
1.
final SyncApp syncJob = new SyncApp();
Thread t = new Thread (new Runnable () {
                         #Override
                         public void run () {
                             synchronized (syncJob) {
                                 String s = syncJob.insert (newJobs, GlobalVariables.URL_LOCALHOST + "jobs");
                                 txtState.setText (s);
                             }}});
                         }
                     });
                     t.Start ();
// t.run ();
2.
myClass.runOnUiThread(new Runnable() {
public void run() {...}
})
3.
Running code in main thread from another thread
SyncApp:
public class SyncApp {
synchronized public String insert(List<Jobs> job, String... params) {
URL url = null;
HttpURLConnection conn = null;
try {
url = new URL(params[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoInput(true);
conn.setDoOutput(true);
String str = new Gson().toJson(job);
byte[] outputInBytes = str.getBytes();
OutputStream os = conn.getOutputStream();
os.write( outputInBytes );
os.flush();
int responseCode=conn.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line=br.readLine()) != null) {
response+=line;
}
}
else {
response=conn.getResponseMessage();
}
return response;
} catch (Exception e) {
e.printStackTrace();
} finally {
conn.disconnect();
}
return null;
}
}
I need to call a thread, wait for the answer and call another thread. Their answers I must use them in the activity
I need to call a thread, wait for the answer and call another thread.
Their answers I must use them in the activity
Example using async tasks to accomplish objective.
In this code, let A be your activity which needs to call a thread,
wait for the answer and call another thread. Customize as needed.
Since you never wait in UI threads, callbacks are used to accomplish synchronization.
Let A be your activity class:
public class A extends Activity {
// some method in activity where you launch a background thread (B)
// which then completes and invokes callback which then creates and launches
// a background thread (C) which then completes and invokes a callback.
//
// In callback C, you are on the UI thread.
protected void someMethod() {
new B(new B.CallbackB() {
public void result(Object o) {
new C(new C.CallbackC() {
public void result(Object o, Object answerFromB) {
// OK - C is now done and we are on UI thread!
// 'o' is answer from C
// 'answerFromB' also provided
}
}, o).execute(new Object());
}
).execute(new Object());
}
}
Define a class B:
public class B extends AsyncTask<Object, Void, Object> {
public static interface CallbackB {
void result(Object o);
}
private CallbackB cb;
public B (CallbackB cb) {
this.cb = cb;
}
protected Object doInBackground(Object... params) {
// do work and return an answer.
return new Object();
}
protected void onPostExecute(Object result) {
if (cb != null) {
cb.result(result);
}
}
}
Define a class C:
public class C extends AsyncTask<Object, Void, Object> {
public static interface CallbackC {
void result(Object o, Object answerFromB);
}
private CallbackC cb;
private Object answerFromB;
public C (CallbackC cb, Object answerFromB) {
this.cb = cb;
this.answerFromB = answerFromB;
}
protected Object doInBackground(Object... params) {
// do work and return an answer.
return new Object();
}
protected void onPostExecute(Object result) {
if (cb != null) {
cb.result(result, answerFromB);
}
}
}
For reference:
https://stackoverflow.com/a/9963705/2711811
My solution is:
public class Sync extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sync_server);
dao = new DAO(this);
txtState = findViewById(R.id.txt_log);
btnSincro = findViewById(R.id.btn_sincro);
btnSincro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
countCall = 0;
callFlow();
}
});
btnHome = findViewById(R.id.btn_home);
btnHome.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(SyncServerActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
private void callFlow() {
switch (countCall) {
case 0:
templates = toTemplate("url");
break;
case 1:
jobs = toJobs("url");
break;
case 2:
job = ... //select item
res = sendJobs(jobs, "url");
break;
default:
runOnUiThread(new Runnable() {
#Override
public void run() {
btnSincro.setEnabled(true);
txtState.append("\n\nEND");
}
});
}
}
private void nextStep() {
setText(txtState, "\nSync \n" + countCall + "/3");
countCall++;
callFlow();
}
private void setText(final TextView text, final String value) {
runOnUiThread(new Runnable() {
#Override
public void run() {
text.setText(value);
}
});
}
public List<Templates> toTemplate(final String... params) {
final List<Templates> list = new ArrayList<>();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
URL url = null;
BufferedReader reader = null;
HttpURLConnection connection = null;
try {
url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
int responseCode = connection.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("data");
for (int i = 0; i < parentArray.length(); i++) {
Templates item = new Gson().fromJson(parentArray.get(i).toString(), Templates.class);
list.add(item);
}
} else {
response = connection.getResponseMessage();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null)
connection.disconnect();
try {
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
nextStep(); //call next Thread
}
}
});
t.start();
return list;
}
public List<Jobs> toJobs(final String... params) {
final List<Jobs> list = new ArrayList<>();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
URL url = null;
BufferedReader reader = null;
HttpURLConnection connection = null;
try {
url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
int responseCode = connection.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("data");
for (int i = 0; i < parentArray.length(); i++) {
Jobs item = new Gson().fromJson(parentArray.get(i).toString(), Jobs.class);
list.add(item);
}
} else {
response = connection.getResponseMessage();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null)
connection.disconnect();
try {
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
nextStep();
}
}
});
t.start();
return list;
}
public Boolean sendJobs(final List<Jobs> job, final String... params) {
final Boolean[] result = {false};
Thread t = new Thread(new Runnable() {
#Override
public void run() {
URL url = null;
HttpURLConnection conn = null;
try {
url = new URL(params[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoInput(true);
conn.setDoOutput(true);
String str = new Gson().toJson(job);
Log.d(TAG, str);
byte[] outputInBytes = str.getBytes();
OutputStream os = conn.getOutputStream();
os.write(outputInBytes);
os.flush();
int responseCode = conn.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = br.readLine()) != null) {
response += line;
}
result[0] = true;
} else {
response = conn.getResponseMessage();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
conn.disconnect();
nextStep();
}
}
});
t.start();
return result[0];
}
}
Whenever a thread ends, it calls the nextStep() method, which starts the next trhead.

Android : take Data in ListView

Actually in my project, I'm blocked. So, for the first time I ask the community of Stackoverflow. I'm new in development.
So, I have a MySql with my datas and I wan't to see in my application the items of users.
For that, I've this :
public class SuccessActivity extends AppCompatActivity {
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private ListView listView;
protected String meubles[] = new String[100];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_success);
Intent intent = getIntent();
String id = intent.getStringExtra("id");
this.listView = (ListView) findViewById(R.id.liste);
new SuccessActivity.Recup().execute(id);
}
//PRIVATE CLASSE POUR AFFICHER LES MEUBLES
private class Recup extends AsyncTask<String, String, String> {
HttpURLConnection conn;
URL url = null;
#Override
protected String doInBackground(String... params) {
try {
//url d'ou reside mon fichier php
url = new URL("http://opix-dev.fr/mytinyhomme/personne/afficher.meuble.php");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "exception";
}
try {
// parametrage du HttpURLConnection pour recevoir et envoyer des donner à mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
// setDoInput and setDoOutput method depict handling of both send and receive
conn.setDoInput(true);
conn.setDoOutput(true);
// Append parameters to URL
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("id", params[0]);
String query = builder.build().getEncodedQuery();
// Open connection for sending data
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
conn.connect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return "exception";
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return "exception";
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String resulta) {
//this method will be running on UI thread
if (resulta.equalsIgnoreCase("false")) {
} else if (resulta.equalsIgnoreCase("exception") || resulta.equalsIgnoreCase("unsuccessful")) {
} else {
try {
JSONArray nom = new JSONArray(resulta);
System.out.println(nom);
String meubles[] = new String[100];
for (int i = 0; i < nom.length(); i++){
JSONObject jsonobject = nom.getJSONObject(i);
meubles[i]= jsonobject.getString("nom");
System.out.println(jsonobject);
System.out.println(meubles);
item.setText( meubles[i]);
}
System.out.println(meubles);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}
The file.php is correct because the JSONArray in System.print is ok But I've try with some TextView for display the board at the end, but I did not succeed.
How I can use the meuble[0] , meuble[1], meuble[2](it's board of String name of items) in a ListView ?
Here is what you need to do to show your data in a listview,
Modified onPostExecute() method:
#Override
protected void onPostExecute(String resulta) {
//this method will be running on UI thread
if (resulta.equalsIgnoreCase("false")) {
} else if (resulta.equalsIgnoreCase("exception") || resulta.equalsIgnoreCase("unsuccessful")) {
} else {
try {
JSONArray nom = new JSONArray(resulta);
System.out.println(nom);
String meubles[] = new String[100];
for (int i = 0; i < nom.length(); i++){
JSONObject jsonobject = nom.getJSONObject(i);
meubles[i]= jsonobject.getString("nom");
System.out.println(jsonobject);
System.out.println(meubles);
}
ArrayAdapter<String> listAdapter=new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,meubles);
listView.setAdapter(listAdapter);
System.out.println(meubles);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
What's added?
You need an adapter to show items in a listview. You can create your custom adapter class by extending an arrayadapter or you can use an arrayadapter without customizing it as shown.
Added code:
Create a new adapter,
ArrayAdapter listAdapter=new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,list);
Set adapter for your listview,
listView.setAdapter(listAdapter);

read from json (string) android with Gson

its my json file
{"VisitorsList":[{"VisitorID":"09005451","VisitorName":" xxxx","VisitorPhon":"","VisitorAddr":"xxxx","GeoCode":"","AutoKey":1},{"VisitorID":"09005468","VisitorName":"xxxxxx","VisitorPhon":"09005468","VisitorAddr":"xxxx","GeoCode":"","AutoKey":2}]}
and i wanna read and show information from this file to a ListView
my VisitorsListActivity is:
public class VisitorsListActivity extends AppCompatActivity {
public ListView lstVisitors;
static VisitorsList visitorsList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.visitor_list);
try {
//********************************** COMELETE THIS SECTION *********************************************
new JsonHelper.GetJsonData(new JsonHelper.GetJsonData.AsyncResponse() {
#Override
public void processFinish(String output) {
try {
if (output == null) output = "";
if (output.equals("")) {
Toast.makeText(getApplicationContext(),
"No Visitor Founded",
Toast.LENGTH_LONG)
.show();
return;
}
//960105--------------------
else if (output.equals("401")) {
Toast.makeText(getApplicationContext(),
"Error 401",
Toast.LENGTH_LONG)
.show();
return;
}
//--------------------------------------
Log.i("LOG", "output" + output);
Gson gson = new Gson();
output = output.substring(1, output.length() - 1);
/*Toast.makeText(getApplicationContext(),
output,
Toast.LENGTH_LONG)
.show();*/
visitorsList = new VisitorsList();
visitorsList = gson.fromJson(output, VisitorsList.class);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"exception",
Toast.LENGTH_LONG)
.show();
}
}
}).execute("http://192.168.1.162:8014/api/Visitors");
//************************************ visitor list is null :| *******************************************
/*if( visitorsList == null) {
Toast.makeText(getApplicationContext(),
"data is nul",
Toast.LENGTH_LONG)
.show();
}*/
AdapterVisitor customAdapter = new AdapterVisitor(this, R.layout.visitor_list, visitorsList.VisitorsList);
customAdapter.notifyDataSetChanged();
lstVisitors.setAdapter(customAdapter);
lstVisitors.requestFocus();
final ViewGroup layoutClear = (ViewGroup) findViewById(R.id.layoutClear);
layoutClear.setVisibility(View.GONE);
} catch (Exception e) {
e.getMessage();
}
} }
and VisitorsList:
public class VisitorsList {
public VisitorsList() {}
public ArrayList<Visitors> VisitorsList;}
Visitors:
public class Visitors {
public String VisitorID;
public String VisitorName;
public String VisitorPhon;
public String VisitorAddr;
public String GeoCode;
public int AutoKey;}
and always visitor list which created by Gson is null. i dont know maybe my problem is in reading from json or maybe visitors class ...
jsonhelper :
public class JsonHelper {
public static class GetJsonData extends AsyncTask<String, Void, String> {
public interface AsyncResponse {
void processFinish(String output);
}
public AsyncResponse delegate = null;
public GetJsonData(AsyncResponse delegate) {
this.delegate = delegate;
}
#Override
protected String doInBackground(String... strUrl) {
String str = strUrl[0];
URLConnection urlConn = null;
BufferedReader bufferedReader = null;
try {
URL url = new URL(str);
urlConn = url.openConnection();
urlConn.setReadTimeout(300000);
urlConn.setConnectTimeout(5000);
bufferedReader = new BufferedReader(new InputStreamReader(urlConn.getInputStream(), "utf-8"), 8);
StringBuffer stringBuffer = new StringBuffer();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line);
}
String tmpJson = stringBuffer.toString().replace("\\", "");
return tmpJson;
} catch (Exception ex) {
ex.getMessage();
return null;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
#Override
protected void onPostExecute(String response) {
delegate.processFinish(response);
}
}
public static class SetJsonData extends AsyncTask<String, Void, String> {
String responseServer;
public interface AsyncResponse {
void processFinish(String output);
}
public AsyncResponse delegate = null;
public SetJsonData(AsyncResponse delegate) {
this.delegate = delegate;
}
#Override
protected String doInBackground(String... param) {
URL url;
String response = null;
try {
url = new URL(param[0]);
HttpURLConnection conn = null;
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(20000);
conn.setConnectTimeout(10000);//950718
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(param[1]);
writer.flush();
writer.close();
os.close();
int responseCode = conn.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = br.readLine()) != null) {
response += line;
}
} else {
response = (String.valueOf(responseCode));
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));//950427
while ((line = br.readLine()) != null) {
}
}
return response;
} catch (IOException e1) {
e1.getMessage();
return null;
} catch (Exception e) {
e.getMessage();
return null;
}
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
try {
super.onPostExecute(result);
delegate.processFinish(result);
} catch (Exception e) {
e.getMessage();
}
}
}}
your visitors class is missing annotations.
use this to convert it properly:
http://www.jsonschema2pojo.org/
Check this https://kylewbanks.com/blog/Tutorial-Android-Parsing-JSON-with-GSON
to read the JSON with GSON.
well at first read AsyncResponse so you are using asynchronous request is that what are doing ?
An asynchronous request doesn't block the client so it continue executing the code when the response is back it will execute what is inside the callback.
But you are calling the customAdapter.notifyDataSetChanged(); outside processFinish() you need to call it inside or call the Adapter work inside the processFinish method.
public class VisitorsList {
public VisitorsList() {}
public ArrayList VisitorsList= new ArrayList<>();}
Should be like this... Intialization is missing.
VisitorsList class :
public class VisitorsList {
#SerializedName("VisitorsList")
public List<VisitorsList> VisitorsList;
public static class VisitorsList {
#SerializedName("VisitorID")
public String VisitorID;
#SerializedName("VisitorName")
public String VisitorName;
#SerializedName("VisitorPhon")
public String VisitorPhon;
#SerializedName("VisitorAddr")
public String VisitorAddr;
#SerializedName("GeoCode")
public String GeoCode;
#SerializedName("AutoKey")
public int AutoKey;
}
}
delete this line
output = output.substring(1, output.length() - 1);
and get your result:
Gson gson = new Gson();
visitorsList=gson.fromJson(output), new TypeToken<VisitorsList>() { }.getType());
i change VisitorsListActivity same as below . and set a condition before call adapter to be sure reading information from json has been finished, this worked correctly :
new JsonHelper.GetJsonData(new JsonHelper.GetJsonData.AsyncResponse() {
#Override
public void processFinish(String output) {
try {
if (output == null) output = "";
if (output.equals("")) {
Toast.makeText(getApplicationContext(),
"No Visitor Founded",
Toast.LENGTH_LONG)
.show();
return;
}
else if (output.equals("401")) {
Toast.makeText(getApplicationContext(),
"Error 401",
Toast.LENGTH_LONG)
.show();
return;
}
Log.i("LOG", "output" + output);
Gson gson = new Gson();
output = output.substring(1, output.length() - 1);
try {
visitorsList = new VisitorsList();
visitorsList = gson.fromJson(output, VisitorsList.class);
if(visitorsList != null) {
d.cancel();
adapter = new AdapterVisitor(visitorsList.VisitorsList);
adapter.notifyDataSetChanged();
lstVisitors.setAdapter(adapter);
lstVisitors.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// ******
Object o = lstVisitors.getItemAtPosition(position);
Intent i = new Intent(getApplicationContext(),DateSelectorActivity.class);
Visitors v = (Visitors) o;
i.putExtra("VisitorID", v.VisitorID);
startActivity(i);
}
});
}
}catch (Exception e) {
Log.i("LOG", getAssets().toString() + "exception" + e);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).execute(url);

Convert AsyncTask to RxJava

Bit new to Rx, so am looking for some help on converting the following AsyncTask to Rx, hopefully so I can visualize Rx a bit more with code that I already know that does something. I've found a few other SO answers that were somewhat relevant, but alot of them werent network requests and many used different operators for different answers, so am a bit confused.
Heres the AsyncTask:
Here is my Java code for an WhatsTheWeather App(all code from the MainActivity is included):
public class MainActivity extends AppCompatActivity {
EditText cityName;
TextView resultTextview;
public void findTheWeather(View view){
Log.i("cityName", cityName.getText().toString());
InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(cityName.getWindowToken(), 0);
try {
String encodedCityName = URLEncoder.encode(cityName.getText().toString(), "UTF-8");
DownLoadTask task = new DownLoadTask();
task.execute("http://api.openweathermap.org/data/2.5/weather?q=" + cityName.getText().toString() + "&appid=a018fc93d922df2c6ae89882e744e32b");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cityName = (EditText)findViewById(R.id.cityName);
resultTextview = (TextView) findViewById(R.id.resultTextView);
}
public class DownLoadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection)url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
int data = reader.read();
while(data != -1){
char current = (char) data;
result +=current;
data = reader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
String message = "";
JSONObject jsonObject = new JSONObject(result);
String weatherInfo = jsonObject.getString("weather");
Log.i("Weather content", weatherInfo);
JSONArray arr = new JSONArray(weatherInfo);
for(int i=0; i<arr.length(); i++){
JSONObject jsonPart = arr.getJSONObject(i);
String main = "";
String description="";
main = jsonPart.getString("main");
description = jsonPart.getString("description");
if(main != "" && description != ""){
message += main + ": "+ description + "\r\n"; //for a line break
}
}
if (message != ""){
resultTextview.setText(message);
} else {
Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
}
}
}
Try this.
public void networkCall(final String urls) {
Observable.fromCallable(new Func0<String>() {
#Override
public String call() {
String result = "";
URL url = null;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
try {
String message = "";
JSONObject jsonObject = new JSONObject(result);
String weatherInfo = jsonObject.getString("weather");
Log.i("Weather content", weatherInfo);
JSONArray arr = new JSONArray(weatherInfo);
for (int i = 0; i < arr.length(); i++) {
JSONObject jsonPart = arr.getJSONObject(i);
String main = "";
String description = "";
main = jsonPart.getString("main");
description = jsonPart.getString("description");
if (main != "" && description != "") {
message += main + ": " + description + "\r\n"; //for a line break
}
}
return message;
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Could not find weather", Toast.LENGTH_LONG).show();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(String message) {
if (message != ""){
resultTextview.setText(message);
} else {
Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
}
}
});
}
But, i would recommend to use Retrofit and RxJava together.
There are couple of things you should know before integrating Retrofit.
Try not to use the older version of Retrofit
Retrofit2 is the one which you are supposed to use at current
Try avoiding code integration of Retrofit with RxJava or RxAndroid
at current(Too much complexity for beginner)
Make sure you are familiar with GSON or Jackson too.
HttpClient is depreciated while OkHttp is comparatively faster than HttpUrlConnection which is generally used by Retrofit2
Finally, here the link for the Retrofit2. It is well detailed and easy to understand. Jack Wharton has tried his best to make it simple to understand as possible.

Get unique item id from item list in Android

I was creating android project in that i am using itemlist view and pagination . while clicking on that particular item i want to get that item id.but i am not getting the unique id.
When i use position then each and every page it is getting form 0-9.
i have the field 'audit_id'. i want to assign this values as item id and i want to get . whether it is possible?
My Code is :
private class AsyncLogin extends AsyncTask<String, String, StringBuilder> {
ProgressDialog pdLoading = new ProgressDialog(Tblview.this);
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
#Override
protected StringBuilder doInBackground(String... params) {
try {
// Enter URL address where your php file resides
url = new URL("http://192.168.1.99/ashwad/ims/webservices/alldata.php");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
Toast.makeText(getApplicationContext(), "URL Exception", Toast.LENGTH_LONG).show();
e.printStackTrace();
return null;
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
// setDoInput and setDoOutput method depict handling of both send and receive
conn.setDoInput(true);
conn.setDoOutput(true);
// Append parameters to URL
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("user_id", "sdfa")
.appendQueryParameter("password", "asffs");
String query = builder.build().getEncodedQuery();
// Open connection for sending data
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
conn.connect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return null;
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
result = new StringBuilder();
String next1;
while ((next1 = bufferedReader.readLine()) != null) {
result.append(next1 + "\n");
}
Log.e("dfasf",result.toString());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
conn.disconnect();
}
return result;
}
#Override
protected void onPostExecute(StringBuilder s) {
super.onPostExecute(s);
try {
JSONArray login;
JSONObject obj = new JSONObject(s.toString());
if(s.toString().contains("Result")) {
data = new ArrayList<String>();
login = obj.getJSONArray("Result");
for(int i=0;i<login.length();i++) {
JSONObject c = login.getJSONObject(i);
productsArray = c.getJSONArray(Latest_Products);
TOTAL_LIST_ITEMS=productsArray.length();
int val = TOTAL_LIST_ITEMS%NUM_ITEMS_PAGE;
val = val==0?0:1;
pageCount = (TOTAL_LIST_ITEMS/NUM_ITEMS_PAGE)+val;
for (int j = 0; j < productsArray.length(); j++) {
JSONObject cc = productsArray.getJSONObject(j);
//------------------------------------------------------------------------
Log.e("audit",cc.getString("phone_name"));
String audit_id_str = cc.getString("audit_id");
int audit_id =Integer.parseInt(audit_id_str);
listview.setSelection(audit_id);
data.add(cc.getString("phone_name") +"\n\n"+cc.getString("audit_status") );
loadList(0);
btn_next.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
increment++;
loadList(increment);
CheckEnable();
}
});
btn_prev.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
increment--;
loadList(increment);
CheckEnable();
}
});
//------------------------------------------------------------------------
}
}
pdLoading.dismiss();
//CheckEnable();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
private void loadList(int number)
{
ArrayList<String> sort = new ArrayList<String>();
title.setText("Page "+(number+1)+" of "+pageCount);
int start = number * NUM_ITEMS_PAGE;
for(int i=start;i<(start)+NUM_ITEMS_PAGE;i++)
{
if(i<data.size())
{
sort.add(data.get(i));
}
else
{
break;
}
}
sd = new ArrayAdapter<String>(Tblview.this,android.R.layout.simple_list_item_1,sort);
listview.setAdapter(sd);
}
private void CheckEnable()
{
if(increment+1 == pageCount)
{
btn_next.setEnabled(false);
btn_prev.setEnabled(true);
}
else if(increment == 0)
{
btn_prev.setEnabled(false);
btn_next.setEnabled(true);
}
else
{
btn_prev.setEnabled(true);
btn_next.setEnabled(true);
}
}
}
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int positon1 =position;
String a1 = Integer.toString(positon1);
Toast.makeText(getApplicationContext(),a1,Toast.LENGTH_SHORT).show();
}
});
If you are keeping count of page then you can add page number to item position.
That will give you unique number for each item.

Categories

Resources