CodenameOne Connection Request wait postResponse - java

i've done a rest web service that gives me some contact information like numbers, age ... i get all this information in this function
public static void getRest(String search) {
if(search.equals("")){
json="http://localhost:8080/com.vogella.jersey.first/rest/jsonServices/print/";
} else {
json="http://localhost:8080/com.vogella.jersey.first/rest/jsonServices/print/"+search;
}
ConnectionRequest req = new ConnectionRequest() {
#Override
protected void postResponse() {
}
#Override
protected void readResponse(InputStream input) throws IOException {
JSONParser p = new JSONParser();
Map<String, Object> h = p.parseJSON(new InputStreamReader(input));
ArrayList object=new ArrayList();
for (Entry<String, Object> entry : h.entrySet()) {
object = (ArrayList) entry.getValue();
int i=object.size();
}
for(int i=0; i<object.size();i++){
LinkedHashMap s= (LinkedHashMap) object.get(i);
Risultati.add(s);
}
}
};
req.setUrl(json);
req.setPost(false);
req.addRequestHeader("Accept", "application/json");
InfiniteProgress prog = new InfiniteProgress();
Dialog dlg = prog.showInifiniteBlocking();
req.setDisposeOnCompletion(dlg);
NetworkManager.getInstance().addToQueue(req);
Risultati is an attribute of the class: ArrayList<LinkedHashMap> Risultati;
the problem is that when i call the function getRest("") in this way:
getRest("");
Label contatto=null;
for(int j=0;j<Risultati.size();j++){
LinkedHashMap s=Risultati.get(j);
String nome=(String) s.get("firstName");
String cognome=(String) s.get("lastName");
String numero =(String) s.get("numero");
contatto=new Label(nome+" "+cognome+" "+numero);
}
hi.addComponent(contatto);
it turns that Risultati is null, if i comment the for cycle i notice that the inner function readResponse is executed after...i don't know what i'm doing wrong

I think the point is that you're calling NetworkManager.getInstance().addToQueue(req). According to it's documentation, it will add a connection request (the one you've just created) to a queue. After the connection request is added to the queue, it returns, meaning the request may or may not have been executed by that time.
You have to options to deal with this. In my opinion, the best way would be to update the user interface after the request has completed, as described in the "File System, Storage, Network & Parsing" chapter of the CodeOne manual:
req.addResponseListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
NetworkEvent e = (NetworkEvent)ev;
// ... process the response
}
});
Alternatively, you could replace the call to addToQueue(req) with addToQueueAndWait(req). The latter method waits until the request is processed in the queue. The downside of the latter approach is that your user interface may freeze while the request is being processed, because the UI thread is blocked on the network I/O.

Related

Make multiple API calls and return combined response in minimum time

I have 10 health check URLs which are simply get service
I am hitting them in a loop like below
for(int i=0;i<10;i++){
Response response = given().when().relaxedHttpsValidation().get(url[i]);
list.add(response);
}
return list;
Now the problem is it hits API in series and waiting for a response for all, I just want to hit all API in parallel but combine the result, I tried using threads but unable to get an idea on how to combine the response in case of multi-threading
If I am reading your question right I believe you want to make parallel calls and combine the results, and in that case I would suggest you to make use of TestNG. I had a similar requirement in the past and this link helped me out
Here's a sample code
public class Parallel {
#DataProvider(parallel = true)
public Object[] getURL() {
return new Object[] { "https://reqres.in/api/users/1", "https://reqres.in/api/users/2",
"https://reqres.in/api/users/3", "https://reqres.in/api/users/4", "https://reqres.in/api/users/5",
"https://reqres.in/api/users/6" };
}
ArrayList<String> original = new ArrayList<String>();
#Test(dataProvider = "getURL")
public void stack(String url) {
Response response = given().when().get(url);
JsonPath js = response.jsonPath();
String email = js.getString("data.email");
original.add(js.getString("data.email"));
}
#AfterTest
public void simple() {
System.out.println("List : " + original);
}
}
Just remove (parallel = true) to see how it works sequentially. I have extracted the email field from the response using JSONPath and added to the list
Don't forget to update the POM
Thank you for your quick response i just want to share now how i achieved it
List responseList = new ArrayList();
ExecutorService exec = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
exec.submit(new Runnable() {
public void run() {
String response = executeServiceCall(urlArray[i]);
responseList.add(response);
}
});
} exec.shutdown();
try {
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {
LOGGER.error(e.toString());
}
LOGGER.info("response list is " + responseList)

How to add results of Facebook Graph api to array list in Java

I am using the Facebook graph api to find out what pages a user is apart of. When the query comes back with a json object it has what I need but, for some reason it doesn't want to add to my array list. The correct value is printed in log.d it seems to skip my arraylist for some reason. Any ideas?
Find page function
private ArrayList<String> foundPages;
private JSONObject jsonObject;
public ArrayList<String> findPages()
{
accessToken = AccessToken.getCurrentAccessToken();
foundPages = new ArrayList<>();
GraphRequest request = GraphRequest.newGraphPathRequest(
accessToken,
"/me/accounts",
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
try {
jsonObject = response.getJSONObject();
for(int i=0; i < jsonObject.getJSONArray("data").length(); i++)
{
page = response.getJSONObject().getJSONArray("data").getJSONObject(i).getString("name");
Log.d("viewmodel",page);
foundPages.add(page);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
request.executeAsync();
return foundPages;
}
There is a common way to solve this problem, which is to define a callback method which will return these values to you, AFTER they have been populated by the call, which goes something like this (my java is rusty, bear with me...)
define an interface :
interface Callback{
void apiResponseCallback(ArrayList<Page> result);//whatever your model is, make the array of that type
}
then, in your normal findPages method, change it to this:
public void findPages(Callback callback) {
//
//
........
for(int i=0; i < jsonObject.getJSONArray("data").length(); i++)
{
page = response.getJSONObject().getJSONArray("data").getJSONObject(i).getString("name");
Log.d("viewmodel",page);
foundPages.add(page);
}
callback.apiResponseCallback(foundPages);//here we are returning the data when it is done
}
then, when you call findPages
findPages(new Callback() {
#Override
public void apiResponseCallback(ArrayList<Page> result) {
here, this result parameter that comes through is your api call result to use, so result will be your populated pages to use.
}
});
}
sake of completeness:
public void findPages(Callback callback)
{
accessToken = AccessToken.getCurrentAccessToken();
foundPages = new ArrayList<>();
GraphRequest request = GraphRequest.newGraphPathRequest(
accessToken,
"/me/accounts",
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
try {
jsonObject = response.getJSONObject();
for(int i=0; i < jsonObject.getJSONArray("data").length(); i++)
{
page = response.getJSONObject().getJSONArray("data").getJSONObject(i).getString("name");
Log.d("viewmodel",page);
foundPages.add(page);
}
callback.apiResponseCallback(foundPages);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
request.executeAsync();
}
Yep. This here:
request.executeAsync();
triggers an asynchronous request. But your "current" thread simply continues to do:
return foundPages;
and it returns an empty list.
That list gets later filled, but at the moment in time when that method returns, that list is still empty. Or just gets filled. Who knows, as it gets filled asynchronously, at some unknown point in the future.
A solution could be to have some other variable/field that tells you the data has arrived and pushed into the list.
Alternatively, that method could just make a synchronous request, simply block the caller from progressing until the data has arrived.
You see, you can't have it both ways: when you don't wait for your results to arrive, you shouldn't expect them to be available immediately.

Handle multiple user at the same time with TelegramLongPollingBot and thread

I'm building my first telegram bot. It send one message every 5 seconds to the user.
While it sends it to one user it cannot receive update from other chat.
public void foo(msg, Update update){
msg.setChatId(update.getMessage().getChatId());
for (int i = 1; i < links.size(); i++){
msg.setText(links.get(i));
execute(msg);
}
Thread.sleep(wait * 1000);
}
How can I use Thread? I've tried creating multiple thread here
public static void bot(){
ApiContextInitializer.init();
TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
try {
telegramBotsApi.registerBot(new myBot());
} catch (TelegramApiException e) {
e.printStackTrace();
}
But he tries to create multiple bots and fails. Same if this is the runnable function:
How can I do it? I'm Stuck. I cannot create this function in different thread
public void onUpdateReceived(Update update) {
leggi(new SendMessage(), update.getMessage().getText(), update);
//.setChatId(update.getMessage().getChatId())
public void leggi(SendMessage msg, String command, Update update){
if(command.equals("test") {
foo( msg, update);
}
Here the full code... https://github.com/siamoInPochi/Ilsottomarinobot/tree/prova/src/main/java/Ilsottomarinobot
If you spawn a thread for every bot user who wants to receive messages, you will quickly be out of computer's resources in case of high number of users. So I think threads is not a good idea for your task.
In my mind more natural approach is the following:
Find a library with an HTTP server.
Switch from GetUpdates to webhooks.
Schedule send-message-to-user-every-5-seconds tasks to server's event loop.
Send messages every 5 seconds asynchronously.
You can make it with this library https://github.com/pengrad/java-telegram-bot-api
<dependency>
<groupId>com.github.pengrad</groupId>
<artifactId>java-telegram-bot-api</artifactId>
<version>4.2.0</version>
</dependency>
Subscribe to new updates via bot.setUpdatesListener
Send messages via bot.execute(new SendMessage(chatId, link), callback)
Full working example:
static String[] links = {"1", "2", "3"};
static Callback emptyCallback = new Callback() {
#Override
public void onResponse(BaseRequest request, BaseResponse response) {
}
#Override
public void onFailure(BaseRequest request, IOException e) {
e.printStackTrace();
}
};
static void foo(TelegramBot bot, Update update) {
Message message = update.message();
if (message == null) return;
Long chatId = message.chat().id();
for (String link : links) {
bot.execute(new SendMessage(chatId, link), emptyCallback);
}
}
public static void main(String[] args) {
TelegramBot bot = new TelegramBot(TOKEN);
bot.setUpdatesListener(updates -> {
for (Update update : updates) {
foo(bot, update);
}
return UpdatesListener.CONFIRMED_UPDATES_ALL;
});
}

Return Value In Runnable

I have a custom adapter that buttons and TextView, the TextView is changed on a button click within listview and it after sending and receiving feedback from http Post via Json response, I tried using runnable and assynctask but no success. In the runnable, I can not return a value from the method.
What I wanted is to send http request to the server and return json results, based on the returned results, the TextView will change.
What is the best approach to use to achieve this.
If any one can help point me to a resource that will help me to achieve this will be highly welcome.
Thanks in advance!
Here is my code..
public String getStatus(final String id, final String user){
final String[] resp = {"0/0/0"};
new Thread(new Runnable() {
#Override
public void run() {
// Building Parameters
final List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", user));
params.add(new BasicNameValuePair("id", id));
Log.d("Nay Params", "" + params);
// getting product details by making HTTP request
JSONObject json = jsonParser.makeHttpRequest(NAY_URL, "POST",
params);
// check your log for json response
// json success tag
try {
Log.d("Nay Response", ""+ json);
success = json.getBoolean(TAG_SUCCESS);
yeaSt = json.getBoolean(TAG_E_STATUS);
naySt = json.getBoolean(TAG_A_STATUS);
yeaC = json.getInt(TAG_YEA);
nayC = json.getInt(TAG_NAY);
if (success){
resp[0] = yeaS + "/" + naySt + "/" + yeaC + "/" + nayC;
return resp[0];
//Can not return return value within void method that is; Class void run()
}
} catch (JSONException e) {
e.printStackTrace();
//return resp[0];
}
}
}).start();
//Can not acces json result outside the try catch block
Log.d("sux", ""+success);
// Log.d("Rest1", resp[0]);
return resp[0];
}
You could use Callable interface in order to run a thread and get the thread's result.
Here's the Callable documentation.
And Jakob explains how to use it here.
Hope that helped, if you need a concrete example I recently used this approach in my project, and I'll be happy to provide you with a sample.
Edit:
Here is a simple example of using callable, I changed a little bit my code so it is more clear:
public class Test {
ExecutorService executor;
public Test() {
/* I used an executor that creates a new thread every time creating a server requests object
* you might need to create a thread pool instead, depending on your application
* */
executor = Executors.newSingleThreadExecutor();
}
private JSONObject doTheWork() {
// init
Callable<JSONObject> callable;
Future<JSONObject> future;
JSONObject jsonResult = null;
try {
// create callable object with desired job
callable = new Callable<JSONObject>() {
#Override
public JSONObject call() throws Exception {
JSONObject jsonResult = new JSONObject();
// connect to the server
// insert desired data into json object
// and return the json object
return jsonResult;
}
};
future = executor.submit(callable);
jsonResult = future.get();
} catch(InterruptedException ex) {
// Log exception at first so you could know if something went wrong and needs to be fixed
} catch(ExecutionException ex) {
// Log exception at first so you could know if something went wrong and needs to be fixed
}
return jsonResult;
}
}
Another approach would be creating a class that implements Callable. Whatever of these approaches you choose depends on your application, and maybe person's taste :).
Happy that I helped.

How to execute web request in its own thread?

I am creating an android application which has to execute web requests in the background and then handle the received data and modify the user interface according to the server response.
The goal of posting requests and handling data in the background is to avoid the freezing of user interface. Currently however I notice that the user interface is freezing so I am not sure the logic is working as it is supposed to.
Here is the part of code which is supposed to post requests and handle responses in its own thread and then pass the data to GUI:
public class ServerConnection {
Queue<String> requests;
...
DefaultHttpClient httpClient;
HttpHost targetHost;
Handler handler;
ServerResponseHandler responseHandler;
Activity activity;
public ServerConnection(Activity activity){
this.activity = activity;
this.responseHandler = (ServerResponseHandler) activity;
httpClient = new DefaultHttpClient();
targetHost = new HttpHost(TARGET_DOMAIN, 80, "http");
requests = new LinkedList<String>();
}
private Runnable requestSender = new Runnable(){
#Override
public void run() {
if(!requests.isEmpty()){
String requestString = requests.remove();
HttpGet httpGet = new HttpGet(requestString);
httpGet.addHeader("Accept", "text/xml");
String encodingString = "testuser:testpass";
String sEncodedString = Base64Coder.encodeString(encodingString);
try{
String sContent = fetchURL(requestString, sEncodedString);
XMLParser xmlParser = new XMLParser();
List <Product> products = xmlParser.getProducts(sContent);
responseHandler.onProductsResponse(products);
}
catch(Exception ex){
Log.e(TAG, ex.getMessage());
}
}
}
};
public void sendRequest(String requestString){
requests.add(requestString);
handler = new Handler();
handler.post(requestSender);
}
The method sendRequest() is called from the main activity which implements ServerResponseHandler. I guess the request is executed in its own thread and by calling
responseHandler.onProductsResponse(products);
the list of products (data from the web) is passed to main activity. Anyway due to poor performance I would appreciate if anyone could correct any possible issue in the logic above or suggest any other (better) option.
I'd suggest you take a look at ASyncTask class (available since Android 1.5).
It simplifies the process of creating a background Thread that synchronizes with the GUI thread once it's complete.
You should be able to achieve what you're trying using code something list this
private class DownloadFilesTask extends AsyncTask<String, List<Product>, Integer> {
protected List<Products> doInBackground(String... requestStrings) {
int count = requestStrings.length;
int results = 0;
for (int i = 0; i < count; i++) {
String requestString = requestStrings[i];
HttpGet httpGet = new HttpGet(requestString);
httpGet.addHeader("Accept", "text/xml");
String encodingString = "testuser:testpass";
String sEncodedString = Base64Coder.encodeString(encodingString);
try{
String sContent = fetchURL(requestString, sEncodedString);
XMLParser xmlParser = new XMLParser();
List <Product> products = xmlParser.getProducts(sContent);
results++;
publishProgress(products);
}
catch(Exception ex){
Log.e(TAG, ex.getMessage());
}
}
return results;
}
protected void onProgressUpdate(Integer... progress) {
// TODO You are on the GUI thread, and the first element in
// the progress parameter contains the last progress
// published from doInBackground, so update your GUI
}
protected void onPostExecute(int result) {
// Processing is complete, result contains the number of
// results you processed
}
}
And execute by calling
new DownloadFilesTask().execute(url1, url2, url3);
According to the handler javadoc, I don't think the post() method create any threads. If I'm right it execute the Runnable on the thread to which the handler is attached. So in this case this is the activity thread so the UI thread ! That's why you have poor performance.
You have to implement a Thread which execute your Runnable. But by doing that, you won't be able to update your activity like you currently do by calling :
responseHandler.onProductsResponse(products);
This is because you are not any more in the UI thread, and only the UI thread is authorized to interact with the UI (so the activity).
So you have to replace this call by accessing your Handler.
Message msg = handler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putSerializable( "products", products ); //not sure it will pass here
msg.setData( bundle );
handler.sendMessage( msg );
And implementing the handleMessage() method for your Handler :
#Override
public void handleMessage( Message msg )
{
List <Product> products = msg.getData().getSerializable( "products" );
responseHandler.onProductsResponse(products);
}
Last but not least : the Handler has to still be created in the activity thread.

Categories