I am making an app where i have a url with date.I need to check if the url has data and if it had data then add date to list.I have made a method which i have posted below and it is being call on main thread.But the problem is it takes few seconds to start the app.I need to optimise the app.Is there any other way to "REDUCE THE LOADING TIME".
Code
private List<String> getDateList(int counter, String date) {
String urlth = "https://www.example.com/json/" + date.trim().replaceAll("/", "") + "-12.json";
if (validateUrl.exists(urlth)) {
dateList.add(date);
} else {
date = givePreviousDate(date);
return getDateList(counter, date);
}
if (dateList.size() == 7) {
return dateList;
} else {
date = givePreviousDate(date); //gives previous date
return getDateList(++counter, (date));
}
}
You can use a handler to call your method in background, something like this
Handler handler = new Handler();
ListView<String> myList = new ArrayList<>();
handler.post(new Runnable() {
#Override
public void run() {
//call your method here
myList = getDateList(2, "date"); //with int and date data
}
});
Hope this will help!
Related
I am doing an app where I click the START button and get current time, and hitting STOP gets the time again. I´ve been using system time without any errors, recently I changed it to server time, which is in an Asynctask, but the app is unstable since, slowed down and exits without error messages, but on faster connections it can process. Any idea why? This is my code:
class getDST2 extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
try {
TimeTCPClient client = new TimeTCPClient();
try {
client.setDefaultTimeout(60000);
client.connect("time.nist.gov");
simpledate = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
do_casu = simpledate.format(client.getDate());
} finally {
client.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void result) {
getDSTdone = true;
}
}
Also doing a graphic timer of the current time since Start was clicked so I need to get server time every second inside a handler.. code:
handler.post(r = new Runnable() {
public void run() {
hasStartedtt2 = true;
calendar = Calendar.getInstance();
simpledate = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
new getDST2().execute(); // THIS IS THE ASynctask, returns the "do_casu" String
zaciatok_hour = zaciatok.substring(11, 13);
zaciatok_minute = zaciatok.substring(14, 16);
koniec_hour = do_casu.substring(11, 13);
koniec_minute = do_casu.substring(14, 16);
zaciatok_sekundy = zaciatok.substring(17, 19);
koniec_sekundy = do_casu.substring(17, 19);
final_hour = ((Integer.parseInt(koniec_hour) - Integer.parseInt(zaciatok_hour)));
final_minute = Integer.parseInt(koniec_minute) - Integer.parseInt(zaciatok_minute);
final_seconds = Integer.parseInt(koniec_sekundy) - Integer.parseInt(zaciatok_sekundy) - 1;
}
});
Handler is called every second.
ServerTimeThread sth = new ServerTimeThread();
sth.start();
from_time = simpledate.format(sth.time);
when you call 'sth.time',the thread just start and is still in progress.
'time' is remain uninitialized,it is init at end of thread
So when accessing 'time',it is null absolutely.
2 way for AsyncTask
Blocking operation:
public class NTPDateTask extends AsyncTask<Void,Void,Date> {
#Override
protected Date doInBackground(Void... voids) {
Date date=fetchYourDate();
//fetch your date here
return date;
}
}
then call
Date result = new NTPDateTask().execute().get();
Non-Blocking operation(Callback pattern):
public class NTPDateTask extends AsyncTask<Void,Void,Date> {
#Override
protected Date doInBackground(Void... voids) {
Date date = fetchYourDate();
//fetch your date here
return date;
}
#Override
protected void onPostExecute(Date date) {
//this is 'callback'
//do the thing you want when task finish
//onPostExecute is called when doInBackground finished,and it runs on UIThread
}
}
then
new NTPDateTask().execute();
EDIT:
class TCPTimeDisplayWorker implements Runnable {
static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
boolean isActive = true;
private Handler targetHandler;
public TCPTimeDisplayWorker(Handler targetHandler) {
//pass the handler ref here
this.targetHandler = targetHandler;
}
#Override
public void run() {
while (isActive) {
long startTime = System.currentTimeMillis();
Date date = fetchDateFromTCPClient();
//fetch Server Date here
String currentDateText = simpleDateFormat.format(date);
targetHandler.sendMessage(Message.obtain(targetHandler, 0, currentDateText));
long endTime = System.currentTimeMillis();
long lapse = endTime - startTime;
if (lapse < 1000) {
try {
Thread.sleep(1000 - lapse);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Handler:
// Non-static inner class will hold outer-class reference,may risk in memory leak
static class MainHandler extends Handler {
private WeakReference<TextView> textViewWeakReference;
// declare as WeakRef to avoid memory leak
public MainHandler(Looper looper, WeakReference<TextView> textViewWeakReference) {
super(looper);
this.textViewWeakReference = textViewWeakReference;
}
#Override
public void handleMessage(Message msg) {
if (textViewWeakReference.get() != null) {
//handle the message from message queue here
String text = (String) msg.obj;
textViewWeakReference.get().setText(text);
}
}
}
then
// must use the same handler to send msg from Background thread and
// handle at Main Thread
// a handler create on a thread will bound to that thread
mainHandler = new MainHandler(Looper.getMainLooper(), new WeakReference<>(mTextViewSystemTime));
new Thread(new TCPTimeDisplayWorker(mainHandler)).start();
btw,CamelCase is the common naming convention in Java.
Hope these are helpful.
if (isConnected()) {
Event eInstance = new Event();
theEvents = eInstance.downloadEvents(eventsNightlife, getActivity());
rAdapter = new RecyclerAdapter(theEvents);
recyclerView.setAdapter(rAdapter);
progrsBar.setVisibility(View.GONE);
....
This is part of the code that runs at "onCreateView". The method downloadEvents uses Volley to download JSON data, extract it and return a list of items (theEvents). Now when my app starts, the recycler view is empty. If I go to my home screen out of the app and then run my app again, this time the data sometimes gets downloaded.
I debugged step by step, and at first launch (i mean when the app is not just resuming), theEvents is empty, so the download didn't return or manage to return anything...
Suggestions on how to execute things before the UI has been shown to the user or what actually needs to be done to approach this task better?
Also, I use a swipeRefreshLayout and at its onRefresh method I do:
public void onRefresh() {
Event eInstance = new Event();
theEvents = eInstance.downloadEvents(eventsNightlife, getActivity());
rAdapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
but it doesn't work. I also tried to
rAdapter = new RecyclerAdapter(theEvents);
rAdapter.notifyDataSetChanged();
recyclerView.swapAdapter(rAdapter, false);
still not working.
EDIT: My downloadEvents method implementing Volley:
public List<Event> downloadEvents(String urlService, Context context) {
eventsList = new ArrayList<>();
RequestQueue requestQueue = Volley.newRequestQueue(context);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
(Request.Method.GET, urlService, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
String durationStr = null;
for (int i = 0; i < response.length(); i++) {
JSONObject eventJson = response.getJSONObject(i);
String title = eventJson.getString("EventTitle");
String body = eventJson.getString("EventBody");
String date = eventJson.getString("EventDate");
String time = eventJson.getString("EventTime");
int duration = Integer.parseInt(eventJson.getString("EventDuration"));
if (duration > 60) {
durationStr = "Duration: " + duration / 60 + " h";
} else if (duration < 60) {
durationStr = "Duration: " + duration + " m";
}
String place = eventJson.getString("EventPlace");
String organ = eventJson.getString("Organization");
Event event = new Event(title, body, date, time, durationStr, place, organ);
eventsList.add(event);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY ERROR", "" + error);
}
}
);
requestQueue.add(jsonArrayRequest);
return eventsList;
}
You can use EventBus for your purpose that is a simple and truth way.
Here, i write an example for how to use EventBus with volley.
Consider that i want to download some data.
This is the class that my download methods is inside it (you can add more methods to it in the future):
Im used volley to download my data:
// Download methods is inside volley
public class MyDownloader{
public static void downloadData(){
DownloadDataEvent dlDataEvent=new DownloadDataEvent();
List<String> myResult=new ArrayList<>();
...
#Override
public void onResponse(JSONArray response) {
super.onResponse(response);
if(respone!=null){
// Do what i want with my received data
dlDataEvent.setData(response);
}
// Post my event by EventBus
EventBus.getDefault().post(dlDataEvent);
...
}
}
}
This is my event:
public class DownloadDataEvent{
private JSONArray mData;
public void setData(JSONArray data){
mData=data;
}
public JSONArray setData(){
return mData;
}
}
Now i want to use my downloadData() method inside my MainActivity:
(I called my downloadData method inside onCreate.)
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
// I have to register this class for EventBus subscriber:
if(!EventBus.getDefault().isRegister(this)){
EventBus.getDefault().registerSticky(this);
}
// Call my downloadData method
if(isConnected()){
MyDownloader.downloadData();
}
}
// And for receive the data through EventBus, i have to create a
// method (subscriber) in this template:
public void onEventMainThread(DownloadDataEvent downloadDataEvent){
JSONArray result=downloadDataEvent.getData();
// Do what i want with my received data
}
}
you can create more than one subscriber every where you want to use received data.
I passed JSONArray to my DownloadDataEvent that it is not good. you can deserialize your received data and pass it to your DownloadDataEvent.
I used Volley to download data
Maybe my descriptions were confusing, but EventBus is a well-known library and is very easy to use.
I've been reading all day threads regarding this issue I came up with a strategy but can't make it work
I have a listview fetching json data from a sql server
this listview already has a on swipe refresh function
I need this listview to refresh automatically only when new row was inserted in the data base.
So I wrote a php file fetching number of rows and echoing it witha 3 second refresh (on the php itself) so every time I enter the php file I get the realtime row numbers of my table.
I'm trying to build a function inside my MainActivity:
int OldNumberOfRows = data from the php file
while(true){
int newNumberOfRows = fetch data again using that php
if(both arent equal) execute refresh command.
}
Note: I got no idea how to extract the string from my asynctask to start manipulating my code with it.
That's it in general, Iv'e added the main activity , the "outer class" (FetchNumRowAsync) calling that php the swipe class and the php itself
MainActivity:
public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {
private String TAG = MainActivity.class.getSimpleName();
private String URL = "http://troyka.esy.es/troyka/orders.php";
private SwipeRefreshLayout swipeRefreshLayout;
private ListView listView;
private SwipeListAdapter adapter;
private List<Order> orderList;
// initially offset will be 0, later will be updated while parsing the json
private int offSet = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new FetchRowNumAsync(this).execute("http://troyka.esy.es/numberofrows.php");
listView = (ListView) findViewById(R.id.listView);
//RelativeLayout.LayoutParams layout_description = new RelativeLayout.LayoutParams(50,10);
//Rl.setLayoutParams(layout_description);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
orderList = new ArrayList<>();
adapter = new SwipeListAdapter(this, orderList);
listView.setAdapter(adapter);
swipeRefreshLayout.setOnRefreshListener(this);
/**
* Showing Swipe Refresh animation on activity create
* As animation won't start on onCreate, post runnable is used
*/
swipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
fetchOrders();
}
}
);
}
/**
* This method is called when swipe refresh is pulled down
*/
#Override
public void onRefresh() {
fetchOrders();
}
/**
* Fetching movies json by making http call
*/
private void fetchOrders() {
// showing refresh animation before making http call
swipeRefreshLayout.setRefreshing(true);
// appending offset to url
String url = URL + offSet;
// Volley's json array request object
JsonArrayRequest req = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
if (response.length() > 0) {
// looping through json and adding to order list
for (int i = 0; i < response.length(); i++) {
try {
JSONObject orderObj = response.getJSONObject(i);
int rank = orderObj.getInt("rank");
String title = orderObj.getString("title");
Order m = new Order(rank, title);
orderList.add(0, m);
// updating offset value to highest value
if (rank >= offSet)
offSet = rank;
} catch (JSONException e) {
Log.e(TAG, "JSON Parsing error: " + e.getMessage());
}
}
adapter.notifyDataSetChanged();
}
// stopping swipe refresh
swipeRefreshLayout.setRefreshing(false);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Server Error: " + error.getMessage());
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
// stopping swipe refresh
swipeRefreshLayout.setRefreshing(false);
}
});
// Adding request to request queue
MyApplication.getInstance().addToRequestQueue(req);
}
}
FetchRowNumAsync:
public class FetchRowNumAsync extends AsyncTask<String, Void, String> {
private Context mContext;
public FetchRowNumAsync(Context ctx){
this.mContext = ctx;
}
protected String doInBackground(String... urls)
{
String fullString = "";
try{
URL url = new URL(urls[0]);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = reader.readLine()) != null) {
fullString += line;
}
reader.close();
}catch(Exception e ){
e.getMessage();
}
return fullString;
}
#Override
protected void onPostExecute(String value){
try{
((OnValueFetchedListener) mContext).onValueFetched(value);
}catch(ClassCastException e){}
}
public interface OnValueFetchedListener{
void onValueFetched(String columns);
}
}
SwipeListAdapter:
public class SwipeListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<Order> orderList;
private String[] bgColors;
public SwipeListAdapter(Activity activity, List<Order> orderList) {
this.activity = activity;
this.orderList = orderList;
bgColors = activity.getApplicationContext().getResources().getStringArray(R.array.movie_serial_bg);
}
#Override
public int getCount() {
return orderList.size();
}
#Override
public Object getItem(int location) {
return orderList.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_row, null);
TextView serial = (TextView) convertView.findViewById(R.id.serial);
TextView title = (TextView) convertView.findViewById(R.id.title);
serial.setText(String.valueOf(orderList.get(position).id));
title.setText(orderList.get(position).title);
String color = bgColors[position % bgColors.length];
serial.setBackgroundColor(Color.parseColor(color));
return convertView;
}
}
PHP
<?php
header("refresh: 3;");
$mysqli = new mysqli("irrelevant","irrelevant","irrelevant","irrelevant");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "SELECT COUNT(*) FROM orders";
$result = mysqli_query($mysqli,$query);
$rows = mysqli_fetch_row($result);
echo ($rows[0]);
$result->close();
$mysqli->close();
?>
Try this approach:
Create an endpoint in your server like the following:
//http://somesite.com/api/data/pull/check
Then, you can easily check this endpoint that returns some value like true or false depending on whether there is new data inserted into the db.
From the result you receive, you can then decide on whether to refresh your data on the phone by making another HTTP request or not. You always want to avoid making unnecessary requests to the server - remember users spend money every time they use their data plan (service).
I, like in the comments above, recommend having a column with a timestamp that you can check so that you only get the newly added data instead of everything!
I hope this gives you a simple idea on how to approach this issue! Good luck!
android app will not know when you have added/updated data in your table on the server until and unless you call script from app and fetch the data and update in your device.
only if your app has implemented these feature's
push notification- call Script every time you receive notification.
XMPP service- used for chat apps(which is not probably answer for
your question right now)
here is my suggestion for you
From server side:
create timestamp field in your table on server. update it with
current timestamp value every time you do changes(i.e update/add) in
the table.and when when that script is called send it across in json
and make your app save it in sqlite along with data.
server will compare for timestamp posted by app everytime with the
saved timestamp in the server for new data.
from client side:
for fist time timestamp from app will be 0. server will check it and
send the whole data along with the timestamp saved during changes in
table. save the data along with time stamp . second time when the
script is called App will be sending the timestamp that was last
saved.
with all this your app will not come to know still if new data is added until you call script and check. but atleast it will come to know if new data is received or not and whether to refresh ur screen
now comes script calling part from client side that is executing of assynch task, do it using handler to execute assynch class every minute
final Handler timerHandler = new Handler();
Runnable timerRunnable;
timerRunnable = new Runnable() {
#Override
public void run() {
new FetchRowNumAsync(context).execute(url);
timerHandler.postDelayed(timerRunnable, 60000); // run every minute
}
};
and unregister it in onDestroy()
#Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
timerHandler.removeCallbacks(timerRunnable);
}
I am trying to make a complex SQLite query using AsyncTask and it results in ANR. I can get where the problem is. Here is my AsyncTask class:
private void callBackground(String type, int page, Date date){
SetParamsForQuery params = new SetParamsForQuery(type, page, date);
backgroundTask backgroundTask = new backgroundTask();
backgroundTask.execute(params);
}
private static class SetParamsForQuery {
String type;
int page;
Date sDate;
public SetParamsForQuery(String type, int page, Date date) {
this.type = type;
this.page = page;
this.sDate = date;
}
}
private class backgroundTask extends AsyncTask<SetParamsForQuery, Void, HashMap<String, ArrayList<ArrayList<esProperty>>>>
{
#Override protected void onPreExecute()
{
}
#Override protected HashMap<String, ArrayList<ArrayList<esProperty>>> doInBackground(SetParamsForQuery... params) {
return esData.requestData(params[0].type, params[0].page, params[0].sDate);
}
#Override protected void onPostExecute(HashMap<String, ArrayList<ArrayList<esProperty>>> result)
{
Log.d(TAG, " result "+ result.size());
if(mode == R.string.today)
otherChart(result, TODAY);
if(mode == R.string.week)
otherChart(result, WEEK);
if(mode == R.string.month)
otherChart(result, MONTH);
}
}
here is my requestData method
public HashMap<String,ArrayList<ArrayList<esProperty>>> requestData(final String mode, final int page,final Date second){
es = new esDatabaseHandler();
HashMap<String, ArrayList<ArrayList<esProperty>>> hash = new HashMap<>();
try{
ActiveAndroid.beginTransaction()
for (int i = 0; i < 24; i++) {
if (page == 1) {
Calendar c = Calendar.getInstance();
hash = es.createHash(es.getDayFromToday(c.getTime(), too, page), null, mode);
}
else {
hash = es.createHash(es.getDayFromToday(second, too, page), null, mode);
}
}
Log.d(TAG, " Background "+ hash.size());
ActiveAndroid.setTransactionSuccessful();
}
finally {
ActiveAndroid.endTransaction();
}
}
The method requestData is running queries in loop in SQLite and returning hash. I know the reasons why ANR happens but it seems like I am doing correct
Well, syntax is correct, but you are forcing UI update all at once in your onPostExecute method. You should update the Activity little by little, extracting a bunch of data and passing it to publishProgress() AsyncTask method. Your way, it is too much to handle for the Main Thread.
I have a Listview that is using the swipefresh feature, and I've encountered a weird problem. When I swipe down, I see the animation and my information (updates behind the scenes.) However, I can't see the updated information, UNTIL I physically scroll down and back up again. The moment I scroll back up towards the top the old data is replaced with the new data.
swipe//
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_green_light);
final TextView rndNum = (TextView) findViewById(R.id.timeStamp);
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
Log.i("Refreshing", " onRefresh called from SwipeRefreshLayout");
initiateRefresh();
}
});
Asynctask//
private void initiateRefresh() {
Log.i("iRefreshing", "initiateRefresh");
/**
* Execute the background task, which uses {#link android.os.AsyncTask} to load the data.
*/
new bgRefresh().execute();
}
private class bgRefresh extends AsyncTask<Void, Void, Boolean> {
static final int TASK_DURATION = 3 * 1000; // 3 seconds
#Override
protected Boolean doInBackground(Void... params) {
// Sleep for a small amount of time to simulate a background-task
try {
Thread.sleep(TASK_DURATION);
} catch (InterruptedException e) {
e.printStackTrace();
}
ArrayList<String> blah = new ArrayList<>();
try {
// Simulate network access
Calendar cal = Calendar.getInstance();
SimpleDateFormat month_date = new SimpleDateFormat("M");
String monthName = month_date.format(cal.getTime());
int lastDayOfMonth =(cal.getActualMaximum(Calendar.DAY_OF_MONTH));
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
int year = Calendar.getInstance().get(Calendar.YEAR); ;
Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);
cal.set(Calendar.DAY_OF_MONTH,1);
monthName = month_date.format(cal.getTime());
//String test = cal.getTime();
//start_date_monthly_statements=5/1/15&end_date_monthly_statements=5/27/15&activity_detail_type=all®_captcha=&display=
String startDateRecentActivity = monthName + "/1/" + currentYear;
String enddateRecentyActivity = monthName + "/" + lastDayOfMonth + "/" + currentYear;
///second calendar
Calendar cal2 = Calendar.getInstance();
cal2 = Calendar.getInstance();
// cal.add(Calendar.DAY_OF_MONTH, -5); //Go back to the previous month
webCreate web = new webCreate();
try {
//Clear and go.
Fields.clear();
Values.clear();
Fields.add("data1");
Values.add(datav1");
cal = Calendar.getInstance();
month_date = new SimpleDateFormat("MM-dd-yyyy hh:mma");
String date = month_date.format(cal.getTime());
date = date.replace("-", "/");
date = date.replace(" ", "\n");
refreshTS = (TextView) findViewById(R.id.timeStamp);
refreshTS.setText(date);
mMainListAdapter = new CustomListViewAdapter(getApplicationContext(), Fields, Values);
mAdapter.n
} catch (Exception e) {
e.printStackTrace();
return false;
}
Thread.sleep(2000);
} catch (InterruptedException e) {
return false;
}
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
mAdapter.notifyDataSetChanged();
// Tell the Fragment that the refresh has completed
onRefreshComplete(result);
}
}
private void onRefreshComplete(Boolean result) {
Log.i("LOG_TAG", "onRefreshComplete");
// Remove all items from the ListAdapter, and then replace them with the new items
//mListAdapter.clear();
//for (String cheese : result) {
// mListAdapter.add(cheese);
//}
// Stop the refreshing indicator
swipeLayout.setRefreshing(false);
}
What would or could cause this?
Looks like from my view of the code you have two adapters? mMainListAdapter and mAdapter? Since the data only appears when you scroll back, this means that you aren't properly notifying the adapter that you have updated the data. Call the notifyDatasetChanged() on the other adapter, since mMainListAdapter appears to be the main adapter.
You have to notify the adapter about the update with notifyDataSetChanged, or create a new adapter. This is on the method SwipeRefreshLayout.setOnRefreshListener. Follow this example:
https://www.bignerdranch.com/blog/implementing-swipe-to-refresh/
Edit
Since your last update I can see that mMainListAdapter is your adapter. Then in your onPostExecute set the adapter to the ListView.
myListView.setAdapter(mMainListAdapter);
Repleace myListView with your ListView