how to make infinite loop in android? - android

I d like to make a while(true) in my code but ,when i run, i don t see anything:
I've tried with AsyncTask but i think that a infinite loop it's too heavy.
public class openActivity extends AppCompatActivity {
ArrayList<String> myArraylist = new Arraylist<> ();
CustomAdapter myAdapter;
ListView list;
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.myActivity);
list = findViewById(R.id.myList);
try {
while (true) {
Document doc = Jsoup.connect(myUrl).get;
//here i get info i need
//add that info to myArraylist
myAdapter = new CustomAdapter(this, myArraylist);
list.setAdapter(myAdapter);
myAdapter.notifyDataSetChanged();
while (myArrayList.get(0).equals(myArraylist.get(0))) {
Thread.sleep(900000);
}
}
} catch (Exception ex) {
ex.getLocalizeMessage()
}
}

Your loop is blocking the UI thread. To perform a periodic task you should use a ScheduledExecutorService.
Also, avoid recreating the adapter on every iteration. Update the existing data and use DiffUtils to notify the changes.

or you can try this :
myAdapter = new CustomAdapter(this, myArraylist);
list.setAdapter(myAdapter);
getData();
public void getData(){
Document doc = Jsoup.connect(myUrl).get;
//here i get info i need
//add that info to myArraylist
myAdapter.notifyDataSetChanged();
getData()
}

Related

Unable to add objects to custom list view from FirebaseMessagingService

Initially, after setting up custom listview, no more items are getting added i.e displayed in list view inspite of adding Object item from FirebaseMessagingService.
I have declared listView static so that Object can be added to the list from other classes or services.
Here's my code:
FirebaseMessagingService:
#Override
public void onMessageReceived(final RemoteMessage remoteMessage) {
//Toast.makeText(getApplicationContext(), remoteMessage.getData().get("transaction"),Toast.LENGTH_SHORT).show();
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
Gson gson = new Gson();
Block b = gson.fromJson(remoteMessage.getData().get("transaction"), Block.class);
OpenChain.arrayList.add(b);
}
});
}
ListView activity code:
public static ArrayList<Block> arrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_open_chain);
arrayList = new ArrayList<>();
getSupportActionBar().setTitle("Vote Ledger");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ListView listView = (ListView) findViewById(R.id.listView);
BlockchainAdap adap = new BlockchainAdap(this, arrayList);
listView.setAdapter(adap);
adap.notifyDataSetChanged();
}
**I am receiving object from cloud in json format
**Also able to add objects from within listview activity but not from FirebaseMessagingSerivce
I have declared listView static so that Object can be added to the
list from other classes or services.
Not, a good solution, you are leaking arrayList here, as it wont be garbage collected when activity gets destroyed.
A better approach would be to use LocalBroadCast in this scenario.
Checkout the link for info
https://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html
Now, what you are doing wrong. You, are modifying the arraylist but you are not notifying the adapter about the same.
Try this..
private ArrayList<Block> arrayList = new ArrayList<>();
private BlockchainAdap adap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_open_chain);
getSupportActionBar().setTitle("Vote Ledger");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ListView listView = (ListView) findViewById(R.id.listView);
adap = new BlockchainAdap(this, arrayList);
listView.setAdapter(adap);
}
public static void updateList(Block b){
arrayList.add(b);
adap.swap(arrayList);
}
In FirebaseMessagingService
#Override
public void onMessageReceived(final RemoteMessage remoteMessage) {
Gson gson = new Gson();
Block b = gson.fromJson(remoteMessage.getData().get("transaction"), Block.class);
OpenChain.updateList(b);
}
Also, expose a method in your ** BlockchainAdap** for swap.
class BlockchainAdap {
ArrayList<Block> arrayList;
BlockchainAdap(ArrayList<Block> arrayList){
this.arrayList = arrayList;
}
public void swap(ArrayList<Block> arrayList){
this.arrayList = arrayList;
notifydatasetChanged();
}
// other methods
}
This will work, but use
LocalBroadcastReceiver from messaging service to OpenChain activity.
Use RecyclerView instead of ListView.

Android ListView does not show list items

I wanna add items to my list but it only shows the first one:
public class MainActivity extends Activity {
Server server;
TextView infoip, msg;
TextView usersTitle;
String[] array = {"a"};
ArrayList<String> lst;
ArrayAdapter<String> adapter;
ListView userList;
#Override
public void onCreate(Bundle savedInstanceState) {
lst = new ArrayList<String>(Arrays.asList(array));
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, lst);
userList = (ListView) findViewById(R.id.userList);
userList.setAdapter(adapter);
From this other class method, everytime it is called I want the text to go below the first one. The method certainly runs but it does not put the text below the previous one. It just shows "a"! Anyone knows why?
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.lst.add(message);
activity.adapter.notifyDataSetChanged();
}
});
I have also tried:
adapter.insert(String, int);
lst.add(int, String);
And even added in the onCreate method this:
lst.add(1, "2");
adapter.notifyDataSetChanged();
And still doesnt add the "2"!!
If you are adding items to Arraylist from another class ,you have to declare your Arraylist Static.So that it can hold items in memory.
Replace ArrayList lst with public static ArrayList
Here is the solution to your Problem.I have created an Activity class and Tests java class.
public class MainActivity extends Activity {
String[] array = {"a"};
public static ArrayList<String> lst;
ArrayAdapter<String> adapter;
ListView userList;
Tests tests = new Tests();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userList = (ListView) findViewById(R.id.userList);
lst = new ArrayList<String>(Arrays.asList(array));
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, lst);
userList.setAdapter(adapter);
tests.callThread();
}
}
Here is the Tests.java Class
public class Tests {
int i = 0;
String message = "";
Thread runOnUiThread;
public void callThread()
{
new Thread(new Runnable() {
#Override
public void run() {
try {
while (i < 10) {
i = i + 1;
message = String.valueOf(i);
//Create a server socket object and bind it to a port
MainActivity.lst.add(message);
}
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
}
Just call your service inside this thread where I have incremented variable i and by this way you can populate the list in right order.
Can you tell whether the other class is Activity or Fragment ?
And while adding the data into Arraylist, you don't need the Thread to be run in order to insert new data to Arraylist
Try to make "lst" and "adapter" both static.
I'm suspicious about the runOnUiThread. Can you provide more information why did you use this function? Also i highly recommend using RecyclerView
Also you can refer to this post for adding items to RecyclerView

How to refresh Android ListView from inside one function

I have a problem about refreshing the screen after i add a string to my listview. I add the string and then i use adapter.notifyDataSetChanged() but the screen doesn't refresh until the function is over. I need it to refresh immediately after i add the string to the listview
public class MainActivity extends AppCompatActivity {
public ArrayList listaConectados;
private TextView estado;
private ListView listaView;
public static int x;
private ArrayAdapter<String> adapter;
private ArrayList<String> arrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
estado = (TextView)findViewById(R.id.estado_TextView);
listaConectados = new ArrayList<Dispositivos>();
arrayList = new ArrayList<String>();
listaView = (ListView) findViewById(R.id.listaConectados_listView);
adapter = new ArrayAdapter<String>(getApplicationContext(),
android.R.layout.simple_list_item_1,arrayList);
listaView.setAdapter(adapter);
}
public void searchConnectedDispositives(View view) {
ArrayList listaParaActualizar = new ArrayList<String>();
int i;
int x;
String ip = getIpAddress();
String ipVariable = ip.substring(0,10);
for(i=0;i<255;i++){
int result=10;
String ipTemp = ipVariable +String.valueOf(i);
try {
result=pingHost(ipTemp);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(result==0){
Dispositivos nuevo = new Dispositivos(ipTemp);
arrayList.add(ipTemp);
adapter.add(ipTemp);
adapter.notifyDataSetChanged();
}
}
The function searchConnectedDispositives is called when I touch one button. When this function ends, the Activity is refreshed.
Observing your code leads me to find out that the real cause of your problem is pingHost() which has proc.waitFor(); and waitFor() is a blocking call.
That means you are holding the UI thread (because this is the thread where you are performing your operation).
And the reason why your ListView gets refreshed only in the last and I'm sure it gets updated only in the last iteration of your for loop is the same problem as here and I have posted the answer for the same. You can read it .

How to declare ArrayList in android?

I want to declare arrayList into this line:
public class tlcity extends Activity {
//ArrayList<String> idArray = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
and into the other method,for example this method:
protected void onPostExecute(String result) {
//fill the arraylist
...
and into the other method for example this method read arraylist data:
public void readlist(){
//read the arraylist data and show
}
How can i do this?
You can declare ArrayList like this
ArrayList<String> list;
list = new ArrayList<String>();
You can add, remove items in ArrayList Like this
list.add("A");
list.remove(0);
ArrayList<String> abc=new ArrayList<String>();
You can initialize or create an instance of your array list like this
idArray = new ArrayList();
You can perform any operations to it using idArray object.
For example you can add items like this
idArray.add("item1");//In you case its a list of strings.
In the same way you would do that in another Java app / class:
public class tlcity extends Activity {
List<String> idArray;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
idArray = new ArrayList<String>();
}
protected void onPostExecute(String result) {
idArray.add("One");
idArray.add("Two");
idArray.add("Three");
...
}
public void readlist(){
for (final String element : idArray) {
// Use the nth string
}
}
I want to declare arrayList into this line:
ArrayList<String> myList;
and into the other method,for example this method:
myList = new ArrayList<String>;
and into the other method for example this method read arraylist data:
for(int i=0; i<myList.size(); i++)
System.out.println(myList.get(i).toString());
If you want to use ArrayList locally then declare it locally. if you want to use it in all methods then declare it globally in class.
public class tlcity extends Activity {
ArrayList<String> idArray = new ArrayList<>(); // to Use this arraylist globally.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<String> localaraaylist = new ArrayList<>(); //to use arraylist in only in oncreate method.
....
According to your post, telling how to declae ArrayList will not enough as you have some methods like onPreExecute() which is a method ofAsyncTask Interface.
Look at this,
public class MainActivity extends ActionBarActivity {
ArrayList<String> arrayList; // declaring ArrayList here
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arrayList = new ArrayList<String>(); // Initializing arrayList
arrayList.add("initial text"); // adding a data to arrayList
ListView listView = (ListView)findViewById(R.id.listView);
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,arrayList); // setting the arrayList in ArrayAdapter
listView.setAdapter(adapter);
new LongOperation().execute(); // async Task
}
private class LongOperation extends AsyncTask<Void, Void, Void> {
ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
// progress dialog starts here
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.setMessage("Loading...");
progressDialog.show();
}
#Override
protected Void doInBackground(Void... voids) {
// for understanding purpose, i made a thread to sleep for 5 sec and later it will add A,B & C to ArrayList.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// adding few more items to arrayList
arrayList.add("A");
arrayList.add("B");
arrayList.add("C");
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss(); // dismissing the progress Dialog
adapter.notifyDataSetChanged(); // refreshing listview
readA(); // read the arrayList
}
}
public void readA()
{
for (int i = 0; i<arrayList.size(); i++)
{
Log.d("key",arrayList.get(i));
}
}
}
Output :
If you run the above code, Initially your list view will only contain only one item & after 5 sec loading it will add another 3 items. The below information will print in logcat that reads the ArrayList.
04-13 14:07:32.395 1123-1123/? D/key﹕ initial text
04-13 14:07:32.395 1123-1123/? D/key﹕ A
04-13 14:07:32.395 1123-1123/? D/key﹕ B
04-13 14:07:32.395 1123-1123/? D/key﹕ C

ArrayList not populating in AsyncTask

In my AsyncTask, I use Jsoup to pull all of the p tags from a web page, and I add them to an ArrayList that should then be used by an ArrayAdapter to fill the screen with the posts, but for some reason, the ArrayList is empty when I go to check it after the methods.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
newsItems = new ArrayList<String>();
fillNewsItems();
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
newsItems));
Log.d("news", Integer.toString(newsItems.size()));
}
private class GetNewsItemsTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
try {
Document doc = Jsoup.connect(URL).get();
for (Element e : doc.getElementsByTag("p")) {
newsItems.add(e.text());
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Couldn't fetch articles, try again later.",
Toast.LENGTH_SHORT).show();
}
return null;
}
}
private void fillNewsItems() {
GetNewsItemsTask getNews = new GetNewsItemsTask();
getNews.execute(URL);
}
}
Does anyone know why the log statement in onCreate returns 0, and my list is empty?
AsyncTask has more possibilities than you are using right now. Basically the AsyncTask is a thread (which cannot change UI elements by default) but it provides a special feature: it synchronizes to the UI thread in the method onPostExecute().
So you can use this to set the ArrayAdapter inside the AsyncTask. Feel free to make use of onPreExecute() to show an information dialog.
This code should to the trick:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fillNewsItems();
Log.d("news", Integer.toString(newsItems.size()));
}
private class GetNewsItemsTask extends AsyncTask<Void, Void, ArrayList<String>> {
protected ArrayList<String> doInBackground(Void... urls) {
try {
ArrayList<String> items = new ArrayList<String>();
Document doc = Jsoup.connect(URL).get();
for (Element e : doc.getElementsByTag("p")) {
items.add(e.text());
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Couldn't fetch articles, try again later.",
Toast.LENGTH_SHORT).show();
}
return items;
}
#Override
protected void onPostExecute(ArrayList<String> items) {
newsItems = items; // I assume that newsItems is used elsewhere.
// If that's not the case -> remove it
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
items));
}
}
private void fillNewsItems() {
GetNewsItemsTask getNews = new GetNewsItemsTask();
getNews.execute();
}
This a nice tutorial about asynchronous programming in Android: Android Threads, Handlers and AsyncTask
Most likely because the AsyncTask hasn't finished executing yet.
An AsyncTask is just that, async. It runs in the background at the same time.
It looks like you are expecting your code to block on fillNewsItems() until the AsyncTask
has finished, when in reality it returns almost immediately, right after starting the AsyncTask. So when you are trying to get the size of the list it still is zero, the AsyncTask hasn't finished yet.

Categories

Resources