I'm new to Android development and I've started creating this app where I read an XML feed and list the contents. But even though the feed changes I still get the same data displayed. Although over night the cache seemed to clear itself. I would like to force reading of the feed each time I start my app. I tried the methods described here How to clear cache Android but it didn't help.
My guess is that I would have to do it onCreate in my main activity (at least that's what I have tried so far).
Can anyone point me in the right direction?
Thanks in advance :-)
Here are some code snippets.
From my activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_game);
deleteCache(this);
new ReadLeagueXml().execute();
}
deleteCache is the method from the other thread I linked to.
Then in my doInBackground I have
InputStream inputStream = new URL(xmlURL).openStream();
if (inputStream != null) {
list = parse(inputStream);
}
And finally in my onPostExecute:
ListView matchListView = (ListView)findViewById(R.id.match_list);
List<String> matchArray = new ArrayList<String>();
for (int i = 0; i < matches.size(); i++) {
matchArray.add(matches.get(i).HomeTeam + " - " + matches.get(i).AwayTeam);
}
matchArray.toArray();
matchesArrayAdapter = new MatchListAdapter(ListGameActivity.this, matches);
matchListView.setAdapter(matchesArrayAdapter);
Your code seems perfectly Fine. Also you do not need to "clear cache".
Now back to the question, If i understand your question correctly, The feed is not getting refreshed. This is because you download the new data on onCreate(). So when you launch the app for the first time the data is downloaded. Then the user goes to another application (remember Android will not close your activity, it will simply pause it). So when the user comes back, If the application is not closed Android will resume it! So your onCreate() will not be called again.
In short,
Update the data in onResume() which is called everytime your activity is shown to the user. Move the new ReadLeagueXml().execute(); to onResume() and new data will be downloaded every time the user opens the app.
You might want to look at the Android Activity Life Cycle here
Related
I am trying to check if the app is opened for first time in LIBGDX. I want this logic to be implemented in level selection screen. I want the sprite to get different for the first time. I have implemented the below code,
private static Preferences prefs;
public MenuScreen(MyGame game) {
prefs = Gdx.app.getPreferences("firsttimeopen");
if (prefs.getBoolean("lock",true) ) {
prefs.putBoolean("lock", false);
Gdx.app.log("firsttimeopening" + a, "firsttimeopening" + a);
} else {
Gdx.app.log("secondtimeopening" + a, "secondtimeopening" + a);
}
Here both the condition becomes true when i open the app.I don't know where did I go wrong. I even referred this question stackoverflow and even this question stackoverflowbut nothing helped. Help me. Thanks in advance.
From the wiki:
Your changes to a preferences instance will only get persisted if you explicitly call the flush() method.
Add the line in your code:
prefs.putBoolean("lock", false);
prefs.flush();
I am trying to utilize ChromeCustomTabs into our project. I ran into several issue when I used mayLaunchUrl. I checked the code Google has on the github. I simply set up an button to test the mayLaunchURL (prerender feature), when I looked up the traffic using chrome dev tool. I did the the traffic and tab got trigger and the url got loaded ( it is simply a GET call with params). However, when I click it multiple times, (after 8-10times, with different params everytime), it STOP working. I stop seeing the requests sent out. (Not seen on chrome dev tool, nor the Proxy I set up).
I wonder if there is a limit times ( restriction) for mayLaunchURL feature, in other words, how many pages we can pre-render in this case? Is there a way to manually cancel the pre-render page and free the resource?
is there a restriction in terms of times to bindCustomTabsService? The way I did to call mayLaunchURL is to have an activity and kill the activity once I finish the tab. Can I bind the service each time even I “kill (finish)” the activtiy every time?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
customTabActivityHelper = new CustomTabActivityHelper();
customTabActivityHelper.setConnectionCallback(this);
}
#Override
protected void onStart() {
super.onStart();
customTabActivityHelper.bindCustomTabsService(this);
}
#Override
public void onCustomTabsConnected() {
Boolean mayLaunchUrlAccepted = customTabActivityHelper.mayLaunchUrl(Uri.parse(“the URL?f=“+params), null, null);
// the mayLaunchUrlAccepted always return true in my case. Even when there is no request sent.
}
Yes, mayLaunchURL() are very expensive in terms of battery/RAM/network, so it is throttled on app UID level. But limits get dropped after some time.
Best strategy is to use mayLaunchURL() if the confidence that the user will navigate to the URL is very high.
There is the "low confidence" mayLaunchURL() which is not throttled, but performs a more limited set of actions (currently preconnect, not specified which, may change). The low confidence mayLaunchURL is triggered by providing null as the uri and a list of URLs in otherLikelyBundles.
I would like some help regarding Java - Android MultiThreading
While learning to develop my app in a multi-threading way in order to take advantage of the ever-growing multi-core devices market share (most devices are quad core now, some even octo-core), I ran in a situation where my threads are either being calling twice or running twice.
I just don't why and how.
[EDIT 3]
Alright, I narrowed down the issue : I called the AsyncTask from the onResume() method. Although my app did not lost focus (which would mean a call to onPause() then back to onResume() upon return of focus in which case my threads would be run twice) during the tests, I solved the issue by moving away the call to FetchFriendsList to another place.
So far so good, but since in my tests the app did not loose focus or perhaps it did but I could not witness it (!), I think there is another reason behind so I'd say my problem is not entirely solved ... at least for the moment. It does work though. Perhaps I did solve the issue but I do not know how :(
[end of EDIT 3]
I am implementing last Facebook SDK and I am using it to fetch the end-user friends list, which seems to do the work.
Since I am running this operation in an AsyncTask, I am not using request.executeAsync().
Instead I am using request.executeAndWait(). Facebook JavaDoc does state that this method must only be used if I am not in a the Main UI Thread which is my case otherwise I would get a NetworkOnMainThreadException.
Anyway, this is where the weird behavior is happening.
private final ArrayList<GraphUser> userFriendsList = new ArrayList<GraphUser>();
public final void fetchFriendsList() {
if (this.session != null && this.session.isOpened()) {
final Request requestUserFriendsList = Request.newMyFriendsRequest(
this.session, new Request.GraphUserListCallback()
public final void onCompleted(final List<GraphUser> users, final Response response) {
if (users != null && users.size() > 0) {
Log.v("Retrieved Friends List -> ", String.valueOf(users.size()));
userFriendsList.addAll(users);
}
}
}
);
if (this.asyncFlag)
requestUserFriendsList.executeAsync();
else
requestUserFriendsList.executeAndWait();
}
}
In my case, asyncFlag is set to false because I need to do stuff synchronously in that specific order :
Fetch User Friends List (not on the Main (UI) Thread)
Save friends list on device (separate new thread)
Save friends list on a server (separate new thread)
Following this pattern, the line userFriendsList.addAll(users); is called twice.
In the logcat, the Log.vis showed twice as well, and finally looking with the debugger, the content of the user friends list is made of duplicates.
But that's not all ... step 2 and 3 are indeed two separate threads which are both created and spawned within the same method : public final void asyncSaveFacebookFriendsList().
And guess what, this method is even called twice !
just why ?
At the beginning I was calling the method for step 2 and 3 like this :
[...]
userFriendsList.addAll(users);
asyncSaveFacebookFriendsList(); // it was private before
[...]
This is where the issue started as both line were running twice.
So I thought, alright, I'll call it later like this :
[...]
fetchFriendsList();
asyncSaveFacebookFriendsList(); // it is now public
[...]
But the issue remains still.
If I don't call public final void asyncSaveFacebookFriendsList(), then nothing is run twice.
Why does this issue happen ? Is there something I did not get in Java Threads ?
I do not think this is somehow related to the Facebook SDK because following the same pattern (and doing it also at the same time), I have the same issues when fetching and storing the end-user Twitter friends list.
So I do believe I am doing something wrong. Does someone have any idea in what possible case a thread is called twice ?
Note : all threads are started this way : thread.start(). I am not using any ThreadPool nor the ExecutorService.
In case you need more background context :
Content of AsyncTask : (no need to wonder why Void and Long, I remove the irrelevant code related to it)
private final class FetchFriendsLists extends AsyncTask<Long, Integer, Void> {
protected final Void doInBackground(final Long... params) {
if (params[0] != Long.valueOf(-1)) {
[...]
twitterAPI.fetchUserFriendsList();
publishProgress(1, -1);
}
if (params[1] == Long.valueOf(0)) {
[...]
facebookAPI.fetchFriendsList();
publishProgress(-1, 0);
}
return null;
}
protected final void onProgressUpdate(Integer... flags) {
super.onProgressUpdate(flags);
if (flags[0] != -1)
twitterAPI.asyncSaveFacebookFriendsList();
if (flags[1] == 0)
facebookAPI.asyncSaveFacebookFriendsList();
}
}
As you can see, I start step 2 and 3 in onPublishProgress() which runs on the Main UI Thread. Brefore it was in the doInBackground() method : the issue happens in both cases!
[EDIT]
After further test, it would seem any kind of code is in fact running twice.
I created a simple method called test in which in print a counter. The counter incremente twice as well !
Why you use onProgressUpdate?¿?
onProgressUpdate(Progress...), [...]. This method is used to display any form of progress in the
user interface while the background computation is still executing.
For instance, it can be used to animate a progress bar or show logs in
a text field.
This is used not at the finish of the petition, but when progress increased.
Read this:
http://developer.android.com/reference/android/os/AsyncTask.html
You need to use:
protected void onPostExecute(Long result) {
So I'm porting my Android app over to Kindle, and expected some tweaks for compatibility, but this is getting ridiculous.
The first thing I found out was that apparently running an AsyncTask from onCreate() can cause some problems if you are also initializing your layout from onCreate() as well. That's definitely not the case in regular Android, but the end result I was getting on Kindle was parts of my layout not being displayed at all. Moving the AsyncTask to onStart solved the problem, but this was a bit surprising. I still have a problem invovling this AsyncTask though.
The purpose of this AsyncTask is to load data from online and display the result in the activity's layout. Pretty straightforward, at least on regular Android devices. Just load the data in doInBackground, then in onPostExecute apply the data to the UI to build the page.
However it seems that in some cases (not all) the data from the AsyncTask won't display on screen. for instance, some data is displayed in a GridView. I update the GridView adapter, use the adapter's notifyDataSetChanged() method, and what should happen is that the view is changed to display the data from the adapter. This process on a normal Android device works fine.
On this Kindle however the data doesn't load (again in some cases, not all, which makes this even more frustrating). I've found that if you press the Back button on the Kindle, then drag your finger off of it (so finish() isn't called), the data will sometimes show up! I get the feeling the normal behavior of notifyDataSetChanged() has been altered for Kindle's version of Android, but I'm not sure what else I'm expected to do to show data loaded into an adapter.
Has anyone run into this issue?
Also, I should note in the case of it only happening sometimes, the actual data structure remains constant, but for certain pages it works and others it does not (the app pertains to music, so for example one artist's page loads properly while the other's does not).
I've included the AsyncTask in question, it works perfectly on any Android device so I don't know what use it will be, but here it goes anyway:
private class GetAttendees extends AsyncTask<Void, Void, AttendeesSectionData> {
#Override
protected AttendeesSectionData doInBackground(Void... params) {
JsonHandler jsonHandler = new JsonHandler(getApplicationContext());
return jsonHandler.getEventAttendeesFromFb(mEvent.getFacebookEventId(), JsonHandler.FACEBOOK_FRIENDS_NO_LIKES);
}
#Override
protected void onPostExecute(AttendeesSectionData data) {
if(data != null && !data.isEmpty()) {
if(data.size() > 18) {
ArrayList<String> toShow = new ArrayList<String>();
int friendLimit = data.getFriendsAttendingIds().size();
if(friendLimit > 18)
friendLimit = 18;
for(int i = 0; i < friendLimit; i++)
toShow.add(data.getFriendsAttendingIds().get(i).getImageURL());
int toShowSizeAfterFriends = toShow.size();
if(toShowSizeAfterFriends < 18) {
int othersLimit = data.getNonFriendsAttendingIds().size();
if(othersLimit > 18 - toShowSizeAfterFriends)
othersLimit = 18 - toShowSizeAfterFriends;
for (int i = 0; i < othersLimit; i++)
toShow.add(data.getNonFriendsAttendingIds().get(i).getImageURL());
}
mFbImagesAdapter.setItems(toShow);
}
else
mFbImagesAdapter.setItems(data.unloadIntoOneArrayList());
String caption = String.format(AppSettings.ATTENDEE_HEADER_CAPTION,
//fill in the %s with:
data.getFriendsAttendingIds().size(),
data.getNonFriendsAttendingIds().size());
caption = caption.replace("*", "<b>");
caption = caption.replace("?", "</b>");
mAttendeesCaption.setText(Html.fromHtml(caption));
calculateGridSize(data.size());
}
else {
Print.log("no attendees for event " + mEvent.getVenue_FormattedLocation());
mAttendeesGrid.setVisibility(View.GONE);
mAttendeesHeaderContainer.setVisibility(View.GONE);
}
loadFacebookImages();
}
}
Thanks!
I found the solution. Oh man that took a LONG time, but I finally got it.
It's really dumb. Basically, the xml attribute android:animateLayoutChanges will totally break your layouts. I guess Kindle will attempt to animate, but fail, so the end result is nothing happening. Removing all instances of android:animateLayoutChanges from my app fixed the problem.
I hope someone else who has this issue in the future can save a ton of time by stumbling across this answer.
I have created an application that extensively requires user inputs and interaction and even though I have made sure that I test and catch every possible case that might throw an error I want to be able to create a mechanism that traces the error in case my application crashes on the field.
I want to be able to record the entire flow right from a button click till whatever the user might be selecting or the navigation between the pages in a log file such that in case my application crashes I'm able to study the trace file later and know exactly where the error occurred.
I'm very new to this sort of programming and therefore any pointers on the above will be very helpful! Thank you in advance :]
PS: I'm not even sure whether what im referring to will be correctly called a "log trace" or not so any edit is welcome. :)
EDIT : I also want to be able to save the error report generated and send it to a particular id (similar to 'send an error report to xyz).
UPDATE :
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try {
File myFiles = new File("/sdcard/ScanApp");
if(!myFiles.exists())
{
myFiles.mkdirs();
}
File myFile = new File("sdcard/ScanApp/log.txt");
myFile.createNewFile();
myFile.delete();
myFile.createNewFile();
String cmd = "logcat -d -v time -f "+myFile.getAbsolutePath()+ " -s ActivityManager:V";
Runtime.getRuntime().exec(cmd);
Logs.this.finish();
}
catch (Exception e)
{
flag=1;
error=e.getMessage();
}
I used this in a previous application for recording any application activity and make a textfile and save it to the SD card, but the contents weren't exactly what I was looking for. Is the solution im looking for something along these lines?
Here, check for the link for reference.
In here you create a class say ExceptionHandler that implements java.lang.Thread.UncaughtExceptionHandler..
Inside this class you will do your life saving stuff like creating stacktrace and gettin ready to upload error report etc....
Now comes the important part i.e. How to catch that exception.
Though it is very simple. Copy following line of code in your each Activity just after the call of super method in your overriden onCreate method.
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(this));
Your Activity may look something like this…
public class ForceClose extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(this));
setContentView(R.layout.main);
}
}
Hope this helps...
You need to look up on Exception Handling. That is when your application crashes or any other app level errors occur, the code in the exception block executes. So in that place, log that error in a text-file and which solves your "log trace" issue.
Refer the link for beautiful examples.