Question

Well in app I'm trying to pull the data from sever for every 4 sec,and update the app. I'm using handler,in that I'm calling AsynTask to fetch the data from server for every 4 sec.

Just I'm worried about the instance created for AsynTask every 4'sec causes any problem ?

This is what I'm doing.

private static final int DELAY = 1000 * 4;
final Handler printHandler = new Handler();
private boolean keepLooping = true;
printHandler.postDelayed(printStuff, DELAY);


Runnable printStuff = new Runnable(){
     @Override
     public void run(){
        // call AsynTask to perform network operation on separate thread
         new DownloadMainScore().execute("http://server/root/score.php");
         if(keepLooping)
             printHandler.postDelayed(this, DELAY);
     }
};
Était-ce utile?

La solution

On your choice of concurrency tool:

You are right that this is not so good. AsyncTasks are designed to be useful helpers when designing occasional asynchronous calls that then need to update a UI. As such, in old (< 1.6) versions of Android the maximum thread pool size was 10!

It would be better to go straight to the very robust Java out of which AsyncTask is built. Given you want to do this repeatedly, try a ScheduledExecutorService. I see they've even made a nice example for you.

Or, given that you seem to be getting a score down, best might be to maintain a persistent connection over a protocol like XMPP, for which there are many Java server and clients.

Finally, you might like to look at gcm.

On design issues in general

I see you want to print a score frequently. Once every four seconds in fact. But what's the point is the score hasn't changed? Furthermore, what if you've got a slow internet connection, and eight seconds later the one for four seconds ago hasn't finished? Right now you will set off yet another download request, even though the other one when it comes back will be up to date!

The solution is to decouple the download mechanism and the UI update mechanism. One way to do it is to have your scheduled download on a single threaded executor- not something you can control in an AsyncTask, which when finishes causes the UI to update and show the score.

Wishing you the best of luck!

Code sketch

Don't have environment set up right now, but in a very rough code sketch (check syntax), using a scheduled executor would look like: In class:

private final ScheduledExecutorService downloadScheduler = Executors.newSingleThreadScheduledExecutor(1);

Then elsewhere, wherever you start doing this

final Runnable scoreHttpRunnable = new Runnable() {
    @Override public void run() {
...
//do Http Syncronously here- I guess whatever is in the doInBackground(...) part of that Async task you wrote!
...
final int newScoreResult = ... (do whatever you do here)
...
runOnUiThread(new Runnable() { @Override public void run() { yourView.updateHoweverYouLike(newScoreResult); } })
...
};
downloadScheduler.scheduleAtFixedRate(scoreHttpRunnable, 0, 4, TimeUnit.SECONDS);

Going one of the other two routes is really too much to post in a single answer to a question. That'd be a another SO question if there isn't already one.

Autres conseils

Be sure that next call send to asyc class only after once its done for that make a variable(IsLoadRunning) and make it true in on preExecute() and false in onPOstExecute and add a condition if(!IsLoadRunning){new DownloadMainScore().execute();}

As official documentation states

AsyncTasks should ideally be used for short operations (a few seconds at the most.)

Services can serve better in you case. Have a look at the accepted answer here

@Override
protected String doInBackground(String... params) {
    Log.d(TAG, "type - " + params[0] + ", url = " + params[1] + ", name = " +   params[2]);


    downloadFile(params[1], params[2]);


    return null;
}

here is download method

URL url = new URI(Url.replace(" ", "%20")).toURL();
        URLConnection connection = url.openConnection();
        connection.setConnectTimeout(1000);
        int fileLength = connection.getContentLength();

        mSavePath = CommonUtilities.getFileSavePath(mContext, fileName, fileLength);
        Log.d(TAG, "*** saveFilePath - " + mSavePath);

        InputStream inputStream = connection.getInputStream();
        if (inputStream != null) {
            File file = new File(mSavePath);

            BufferedOutputStream bufferOutputStream = new   BufferedOutputStream(new FileOutputStream(file));
            byte byteArray[] = new byte[1024];
            int len = 0;
            long total = 0;

            while ((len = inputStream.read(byteArray)) != -1) {
                bufferOutputStream.write(byteArray, 0, len);
                total += len;
            }

            bufferOutputStream.flush();
            bufferOutputStream.close();
            inputStream.close();
        } else {
            Log.d(TAG, "*** inputStream is null");

        }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top