Can i catch Volley Debug message programmatically in Android?
For example : D/Volley﹕ [1] Request.finish:...
(From logcat debug log level)
I would like to do something when Volley send this message.
RequestQueue.RequestFinishedListener listener =
new RequestQueue.RequestFinishedListener()
{ #Override public void onRequestFinished(Request request)
{
if(request.equals(yourRequest))
{
// what you want...
}
}
}; requestQueue.addRequestFinishedListener(listener);
Related
I am developing chat app using smack library. I have an issue in group chat. In my app, i am creating a group and in that members are auto-joined.i want to notify all user when I send a message in the group even if they had not initiated a chat.My code is as follow in that I have place listener in init method but unable to receive a message.
multiUserChatManager = MultiUserChatManager.getInstanceFor(mConnection);
mMultiUserChat = multiUserChatManager.getMultiUserChat(to);
mConnection.addAsyncStanzaListener(this, null);
DiscussionHistory history = new DiscussionHistory();
history.setMaxStanzas(0);
mMultiUserChat.addMessageListener(this);
mConnection.addSyncStanzaListener(this, null);
try {
mMultiUserChat.join(from, "", history, SmackConfiguration.getDefaultPacketReplyTimeout());
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
Here is message listener of group
#Override
public void processMessage(Message message) {
Logg.e(TAG,"Message received group..");
}
I don't know why this method does not call when someone send message in group, even I joined group, If I create 1 group and joined 2 users, when 1 user sends message in group then user2 can't able to receive message, but when user 2 send message inside this group then they both are able to receive messages.
Please help me, I can't able to find the solution. Please don't give suggestion which is already deprecated.
Thanks in Advance.!!
I'm full editing answer after full code review. -again-
I suggest to refactor your code to keep separation of roles in more than 1 huge class.
Basically you are especting messages in wrong listener due to many "addasync - addsync" in your code and you are able to receive messages just as side effect of your monster-class-all-in!
I see many optimization you need to apply to your code.
It's too long to explain and out of the question, however, just as example:
1. sendGroupMessage You can check by MultiUserChatManager if you
already joined the chat and then send the message. You must fire a
"join" just once, not everytime you want to send a message.
2. mMultiUserChat.addMessageListener(this);
A listener must be added ONCE or you'll create tons of threads. Probably it works because you have a singleton. While you have a listener, you don't need to add it anymore to that chat if you don't remove it.
mConnection.addSyncStanzaListener(this, null);
Be carefull: you are adding your listener (wich one? You implements tons of listeners with same class) to your connection. Before or later your code will eat an important stanza (prolly a custom IQ) and you'll have an hard to discovery side effects.
mConnection.addAsyncStanzaListener(this, null); same of 3
Check for ProviderManager.addExtensionProvider(), before or later
you'll need some.
Hope that helps.
Try This
step1 : 1 remove this
mConnection.addAsyncStanzaListener(this, null);
mConnection.addSyncStanzaListener(this, null);
Step 2 : add this
private StanzaTypeFilter serverFilter;
private StanzaListener stanzaListener = null;
private XMPPTCPConnection mConnection;
registerStanzaListener(); // where you init connection
public void registerStanzaListener() {
serverFilter = new StanzaTypeFilter(Message.class);
if (stanzaListener != null) {
mConnection.removeAsyncStanzaListener(stanzaListener);
}
stanzaListener = new StanzaListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
processMessage((Message) packet);
}
};
mConnection.addAsyncStanzaListener(stanzaListener, serverFilter);
}
}
In group chat I am attaching single file, while sending the QBMessage object has on 1 attachment but on receive that QBMessage object the same attachment comes twice.
This happens only in group chat. In private chat it works properly
Seems like you are using samples from here as a starting point for your application: https://github.com/QuickBlox/quickblox-android-sdk
I had the same bug with it, so my quick solution was override sendMessage method in GroupChatImpl.java
#Override
public void sendMessage(QBChatMessage message) throws XMPPException, SmackException.NotConnectedException {
if (qbChat != null) {
try {
qbChat.sendMessageWithoutJoin(message);
} catch (SmackException.NotConnectedException | IllegalStateException e) {
}
}
}
I'm trying to write custom analytics log in native Android app. I don't see it in Analytics console. What could be wrong?
I use following code:
public void logEvent(View view) {
WLAnalytics.enable();
String json = "{\"package\": \"mfpStart\" }";
try {
WLAnalytics.log("Custom event", new JSONObject(json));
} catch (JSONException e) {
e.printStackTrace();
}
WLAnalytics.send();
}
Thanks in advance!
You have to make sure you are calling WLAnalytics.setContext(context) for example on your Activity's onCreate method do something like.
class YourActivity extends Activity {
public void onCreate(Bundle bundle) {
// other code
WLAnalytics.setContext(this);
}
}
I have a custom error handler that checks RetrofitError it gets passed and rethrows it as custom exceptions
private static ErrorHandler getErrorHandler() {
return new ErrorHandler() {
#Override
public Throwable handleError(RetrofitError cause) {
switch (cause.getKind()) {
case NETWORK: return new NetworkException(cause);
case HTTP: return new ApiException(cause);
default: return cause;
}
}
};
}
If this is my endpoint
#GET(USERS_GET_URL)
User getUsers() throws NetworkException, ApiException;
while executing synchronous request I try...catch and handle each custom exception as I want. When it is done asynchronously using
#GET(USERS_GET_URL)
void getUsers(Callback<User> cb) throws NetworkException, ApiException;
the handled exception gets rethrown as RetrofitError. The following snippet of code is from CallbackRunnable class of Retrofit which executes the request
try {
final ResponseWrapper wrapper = obtainResponse();
callbackExecutor.execute(new Runnable() {
#Override public void run() {
callback.success((T) wrapper.responseBody, wrapper.response);
}
});
} catch (RetrofitError e) {
Throwable cause = errorHandler.handleError(e);
final RetrofitError handled = cause == e ? e : unexpectedError(e.getUrl(), cause);
callbackExecutor.execute(new Runnable() {
#Override public void run() {
callback.failure(handled);
}
});
}
As it can be seen, my custom exceptions are getting rethrown as RetrofitError which makes me loose valuable information. Is there any way I can bypass custom error handling for just the async requests?
In your ErrorHandler you pathing original RetrofitError as cause, so as result in your Callback#failure(RetrofitError error) to get actual information you need to write next code: error.getCause().getCause(). This error will contain response that server send with all the data.
But error handler was created for sync request and after some time square team decided to close this gap this way. For more info you can read: https://gist.github.com/benvium/66bf24e0de80d609dac0
As for me, I don't recommend to use ErrorHander for async way, because I don't find any good solution to handle different types of error. It was much easier to get data right from initial RetrofitError.
I'm developing an Android Mobile Application and one of the most important functionality of the app itself is being able to talk with a third-party API Service.
The third party service, offering these API, wants a "beacon" to be included into every API request i made.
The "beacon" is a "long integer" and it must be unique and incremental for every request.
The problem is:
I'm firing a couple of these request and i do not know which of these requests will complete first so i'm running into a race condition: where the second request ends quickly before the first request invalidating the first request!
When a button is clicked the following action will be executed:
public void fireRequests(View view)
{
long first_beacon = System.nanoTime();
fireFirstRequest(view, first_beacon);
long second_beacon = System.nanoTime();
fireSecondRequest(view, second_beacon);
}
I'm using Volley in a proper way, setting up callback etc.. example here:
fireFirstRequest method:
public void fireFirstRequest(View view, long beacon)
{
final ThirdPartyLib api_lib = new ThirdPartyLib(getActivity());
api_lib.doOperationA(beacon, new ThirdPartyLib.MyOwnCallback()
{
#Override
public void update(JSONObject jsonObject)
{
try
{
JSONObject result = jsonObject.getJSONObject("response");
/* my code */
Log.d("doOperationA", result)
}
catch (JSONException e)
{
e.printStackTrace();
}
}
});
}
fireSecondRequest method:
public void fireSecondRequest(View view, long beacon)
{
final ThirdPartyLib api_lib = new ThirdPartyLib(getActivity());
api_lib.doOperationB(beacon, new ThirdPartyLib.MyOwnCallback()
{
#Override
public void update(JSONObject jsonObject)
{
try
{
JSONObject result = jsonObject.getJSONObject("response");
/* my code */
Log.d("doOperationB", result)
}
catch (JSONException e)
{
e.printStackTrace();
}
}
});
}
Here is the execution log:
03-12 14:26:56.252 18769-18769/it.example.app D/Volley: queued doOperationA
03-12 14:26:58.124 18769-18769/it.example.app D/Volley: queued doOperationB
03-12 14:26:59.433 18769-18769/it.example.app D/App: doOperationB: {
"error": false,
"payload": {
"foo": "bar"
}
}
03-12 14:27:04.181 18769-18769/it.example.app D/App: doOperationA: {
"error": true,
"errorMessage": "invalid beacon"
"payload": {}
}
The question is: what's the best way to keep track of beacon before firing an API request or to maintain a "execution order" separation even if we are talking of ASync request?
My rough solution is to call the fireSecondRequest() inside the callback of the fireFirstRequest() when i'm completely sure that first request is done.
I know, this is the best way to kill the awesome world of async requests.
modified action:
public void fireRequests(View view)
{
long first_beacon = System.nanoTime();
fireFirstRequest(view, first_beacon);
}
fireFirstRequest modified method with final View parameter:
public void fireFirstRequest(final View view, long beacon)
{
final ThirdPartyLib api_lib = new ThirdPartyLib(getActivity());
api_lib.doOperationA(beacon, new ThirdPartyLib.MyOwnCallback()
{
#Override
public void update(JSONObject jsonObject)
{
try
{
JSONObject result = jsonObject.getJSONObject("response");
/* my code */
Log.d("doOperationA", result)
/* fire second request */
// EDIT
fireSecondRequest(view, System.nanoTime());
}
catch (JSONException e)
{
e.printStackTrace();
}
}
});
}
You didn't add the part of your code which initiates the Volley RequestQueue, but I'm assuming you're creating the default way using:
RequestQueue requestQueue = Volley.newRequestQueue(context, stack);
When you do this, you get a request queue which allows for 4 concurrent requests by default. You can see this by looking at the constructor this method uses to create a request queue:
private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4;
...
public RequestQueue(Cache cache, Network network) {
this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE);
}
You can overcome this issue if instead of using the default method for creating a RequestQueue, you create your own RequestQueue with a thread pool size of 1. This way, there can be no 2 concurrent requests, and requests will be sent in the order they are dispatched.
The downside with this, of course, is that this can dramatically slow down your app. If all requests must wait until the previous request is finished, this creates a serious bottleneck in your app.
Perhaps consider using more than 1 request queue, and only use this special request queue for requests that rely on this special constraint.
Hope this helps.