Question

i have some local html file and i want to show them with infinite scroll method.

NOTE: i cant change the html content, so please don't advice to add javascript to them. i must do it in run time.

so, i figured out that i can execute javascript in runtime via loadUrl("javascript: ....").

i overrided onOverScrolled() method of webView to find out when user reach the end of webView. (it acting carefully, so the problem is not here)

the problem is some times new content attached successfully and other times it didn't geting attached.

in the log i can see that the end of page method get triggered, retrieving new html body get called, executing javascript code get called, but it did not affect.

here is my code, may be something went wrong and i can not see it:

@Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY)
{
    super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
    if(clampedY & reloadFlag) //for first time realodFlag is false, when the WebViewClient.onPageFinished() get called it turn to ture
    {
        if (!(isVerticalScrollPossible(SCROLL_DOWN)))
        {
            reloadFlag = false; 
            currUri = nextResource(currUri); //findout next page
            appendNextPage();
        }

    }
}

private final int SCROLL_DOWN = 1;
private final int SCROLL_UP = -1;

private boolean isVerticalScrollPossible(int direction)
{
    final int offset = computeVerticalScrollOffset();
    final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();
    if (range == 0) return false;
    if (direction < 0) {
        return offset > 0;
    } else {
        return offset < range - 1;
    }
}

public String getNextPageJS(Uri currPage)
{
    String body = getNextPageBody(currPage);
    //Log.d("myTAG", body);
    String jsResult = "javascript:(function() { document.body.innerHTML += '<div id=\"separator\" style=\"height:10px; margin-top:10px; margin-bottom:10px; background-color:#000000;\"></div>" + body + "';})()";
    return jsResult;
}

private void appendNextPage()
{
    reloadFlag = false;
    Thread appendThread = new Thread(null, doAppend, "backgroundAppend");
    appendThread.start();
    Log.i("appendNextPage", "get called");
}

public String rs = "";
private Runnable doAppend = new Runnable()
{
    @Override
    public void run() 
    {
        Log.i("doAppend", "get called + currUri: " + currUri);
        rs = getNextPageJS(currUri);
        //loadUrl(rs);
        appendHandler.sendEmptyMessage(0);
    }       
};

private Handler appendHandler = new Handler()
{
    public void handleMessage(Message msg)
    {
        loadUrl(rs);
        reloadFlag = true;
        Log.i("appendHandler", "get called");       
    }
};

NOTE: sometimes i get this in the emulator log (not in real device):

I/chromium(1339): [INFO:CONSOLE(1)] "Uncaught SyntaxError: An invalid or illegal string was specified.", source: http://localhost:1025/OEBPS/Text/Section0042.xhtml (1)

the number of page is different from time to time, may be it's for bad javasccript code, i don't know.

hints:

1) i'm not javascript coder, so may be the javascript code is not good

2) or maybe calling javascript code several times cause this problem

3) i know that javascript code must execute after page loading completely, so maybe the code called too soon, the problem for this is that onPageFinished() getting called just for first page and it does not called when new content attached via javascript code, i tried to solve this problem using thread, and i think it worked.

UPDATE: i figured out that this code works fine when the html body is small, but when i try to attach large body it didn't work. is loadUrl() method has char limit? or any other idea?

Was it helpful?

Solution

OK, i found the problem, if anyone wants to know.

the problem is that the loadUri() (at least in my case) can not load too many html tag at once (in javascript code i written)

so, the solution is easy, load tags one by one.

here is the code i used:

public ArrayList<String> getNextPageBody(Uri currAddress)
{
    String html = getHtml(currAddress); // this is the all html tags in the next file

    //get body elements as arrayList, using jsoup
    Document doc = Jsoup.parse(html);
    Elements elements = doc.select("body").first().children();
    ArrayList<String> chuncks = new ArrayList<String>();
    for (org.jsoup.nodes.Element el : elements)
    {
        chuncks.add(el.toString());
    }

    return chuncks;
}

public void loadBodyChunk(ArrayList<String> bodyChunks)
{    
    //show a separator for each page
    bodyChunks.add(0, "javascript:(function() { document.body.innerHTML += '<div id=\"separator\" style=\"height:10px; margin-top:10px; margin-bottom:10px; background-color:#000000;\"></div>';}())");
    loadUrl(bodyChunks.get(0));

    for(int i = 1; i < bodyChunks.size(); i++)
    {   
        String jsResult = "javascript:(function() { document.body.innerHTML += '" +  bodyChunks.get(i) + "';}())";
        loadUrl(jsResult);
    }

    reloadFlag = true;
}

EDIT:

also: first the 's in String should be replaced with \' :

body = body.replace("'", "\\'");

then all newline char should be eliminated:

body = body.replaceAll(System.getProperty("line.separator"), " ");

all problem solved.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top