I have a problem with jsoup on android. I have seen the other posts and tried solutions that were suggested there ( re-adding the jars, calling android fix tool, etc.)
I have added the jsoup jar to my android project (using build path), and added the required
internet permission to my manifest.
<uses-permission android:name="android.permission.INTERNET" />
but when I am trying to run my application I am getting
Could not find method org.jsoup.Jsoup.connect, referenced from method com.example.test.MainActivity.onCreate
I have tried to use the android fix tool but it did not solve the problem.
All I have is a main activity and I am trying to call
Document doc = Jsoup.connect("http://en.wikipedia.org/").get();
attached is part of my code
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
Document doc = Jsoup.connect("http://en.wikipedia.org/").get();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You are trying to run your connection in your main thread. Use AsyncTask and it will work.
I.E.
public class JsoupParser extends AsyncTask...
Why you have to use AsyncTask for network connections in android?
AsyncTask is an abstract helper class that enables you to use the UI thread correctly, while performing background operations in a different thread, without having to really handle threads or controllers. Since android is implemented using a single thread model, each time you launch an application, a new thread will be created.
Imagine you have a single thread model where you at a button click will parse a website using Jsoup. This would have worked fine in earler android versions, though you would have had a non-responsive screen until the network operation is done. The AsyncTask will run in the background enabling your screen to still be responsive while another thread takes care of the network communication.
Take a look in the API:
AsyncTask
NetworkOnMainThreadException
Delete all statements like:
System.out.println(something);
It worked for me, realizing this took me 2 hours.
In you normal activity
use this
public static int SDK_INT = android.os.Build.VERSION.SDK_INT;
and before fetching Document
write this inside try block
if (SDK_INT >= 10) {
ThreadPolicy tp = ThreadPolicy.LAX;
StrictMode.setThreadPolicy(tp);
}
it worked for me
Related
I'm trying to carry out junit test for the Android-DDP library.
To initialize the meteor object, we need a reference to a android context which I'm able to achieve using Robolectric. But the web-sockets is probably talking to the server on a different thread because of which the callback methods are not called and the test methods are getting end.
I used netstat to check if the android client is trying to communicate or not. It shows various ping/pong messages. So, Yes it is trying to talk to the server.
I went through this tutorial as well,
Android AsyncTask testing with Android Test Framework. This one tells how to handle the network on UI thread. But nothing seems right.
The sample code, I have worked is:
#Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
#RunWith(RobolectricGradleTestRunner.class)
public class MainActivityTest {
private MainActivity activity;
private Meteor meteor;
private String globalUrl = "ws://10.0.3.222:3000/websocket";
#Before
public void setup() {
activity = Robolectric.setupActivity(MainActivity.class);
meteor = new Meteor(activity, globalUrl);
meteor.reconnect();
/*
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
*/
}
#Test
public void validateMeteorIsConnected() {
assertTrue(meteor.isConnected());
}
}
Any help would be appreciable. Thanks in advance.
You defined two methods, setup() and validateMeteorIsConnected(), but where are they called?
First, your setup is not correct. After your call to new Meteor(...), you don't need the reconnect() call because the constructor does already establish the connection.
Moreover, you must set up a listener so that you know when the connection has been established or data comes in. This is done with mMeteor.setCallback(...); where the parameter is this or activity.
As you said, the work is done on a different thread and everything is asynchronous.
So you can't just call validateMeteorIsConnected() immediately after connecting.
You need some timer, as shown in the question that you linked to.
Since a couple of weeks, I'm seeing more and more crashes of my app with the following exception
Fatal Exception: java.lang.NoClassDefFoundError
android.os.AsyncTask
This code has run for month without any issue, and it seems now to fail on some devices (75% android 2.3.x and 25% android 4.0.3)
It fails when I create a new instance of a class which extends AsyncTask.
I create this class from the UI thread.
How can that class be not found as it's defined within the SDK ?
Yes, looks like it is a problem with one of the versions of Google play Services. See https://code.google.com/p/android/issues/detail?id=81083
A work around is to add:
try {
Class.forName("android.os.AsyncTask");
}
catch(Throwable ignore) {
// ignored
}
into your Application#onCreate()
this appears to ensure that the root classloader loads AsyncTask so that it is then available from within Play Services.
It looks like yet another Google Play Services bug...
https://groups.google.com/forum/#!topic/google-admob-ads-sdk/_x12qmjWI7M
Edit: confirmed by Google staff => https://groups.google.com/d/msg/google-admob-ads-sdk/_x12qmjWI7M/9ZQs-v0ZZTMJ
Same issue here.
I see them for 95% of the cases on android 4.0.3 devices. remaining 5% for 2.3 devices
Errors are randomly occurring from different parts of the code.
Some examples:
java.lang.NoClassDefFoundError: android/os/AsyncTask
at android.webkit.WebView.setupPackageListener(WebView.java:1305)
at android.webkit.WebView.<init>(WebView.java:1176)
at android.webkit.WebView.<init>(WebView.java:1136)
and
java.lang.NoClassDefFoundError: android/os/AsyncTask
at android.webkit.WebView.setupPackageListener(WebView.java:1354)
at android.webkit.WebView.access$10900(WebView.java:363)
at android.webkit.WebView$PrivateHandler.handleMessage(WebView.java:10411)
and
java.lang.NoClassDefFoundError: android.os.AsyncTask
at android.webkit.WebView.setupPackageListener(WebView.java:1385)
at android.webkit.WebView.<init>(WebView.java:1192)
at android.webkit.WebView.<init>(WebView.java:1150)
at android.webkit.WebView.<init>(WebView.java:1135)
at android.webkit.WebView.<init>(WebView.java:1106)
at android.webkit.WebView.<init>(WebView.java:1093)
at com.google.android.gms.ads.internal.util.g.f(SourceFile:400)
at com.google.android.gms.ads.internal.util.g.a(SourceFile:385)
it is completely unclear why these errors are happening. usually i dont see anything in the stacktrace pointing to my code.
I have the same error:
BuscaDatosJugador().execute(participante.getIconImageUrl(),String.valueOf(altoenvio), String.valueOf(contador));
My solution:
final Runnable r = new Runnable()
{
public void run()
{
try {
--- my code ---
}
};
r.run();
}
I experienced same error on android 2.3.3, but same app was stable on 4.0+. It's a Freemium and the error occurs only when in FREE mode, which runs Google Admob adverts. So the error has to be connected with this but I do no have the detail. Here is how I solved the problem:
Execute a statement that would cause the AsyncTask class to be loaded before loading the ads.
steps 1: Create a dummy AsyncTask extension class
public class DummyAsyncTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
return null;
}
}
step 2: just in your main activity:
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new DummyAsyncTask();
.
.some code
.
load your ads here
}
}
After step 2 above, all other code section that instantiates AsyncTask extended class run normally.
I've created an AsyncTask that loads messaging history from a database and then shows it on the device screen:
private void loadHistoryFromDB(Date lastUpdateDate)
{
final class DBAsyncTask extends AsyncTask<Void, Void, List<XMPPMessage>>
{
#Override
protected List<XMPPMessage> doInBackground(Void... arg0)
{
List<XMPPMessage> messages = null;
try
{
messages = PersistenceManager.getXMPPMessagesFromDB(userInfo, 0, messagingActivity);
}
catch (SQLException e)
{
e.printStackTrace();
}
catch (LetsDatabaseException e)
{
e.printStackTrace();
}
return messages;
}
It seems to work fine, but after being executed, it leaves 2 running threads and I can't finish the activity because of that. How can I fix it?
As long as your tasks are executing properly (exits from onPostExecute), this shouldn't be something you have to worry about. Once executed, AsyncTask thread(s) will stick around for possible reuse in the form of a thread pool or single thread, depending on platform version. This is normal behaviour - they will eventually be cleaned-up/reused.
First off, make sure you are calling super.doInBackGround() at the top of your overridden method call.
If that isn't it, it's likely because you are maintaining the connecting to the database.
That is, you still have a lock established on the database.
See if you can explicitly unlock the database, that may fix your problem.
You could put it in the onPostExecute() method.
This problem is most likely due to confusion surrounding the cancel method of AsyncTask.
You need to break down your background task into loopable segments, then Before each loop iteration starts doing your task,you need to check if the task is cancelled and if it is you need to break the loop. There doesn't seem to be any other way to stop an AsyncTask from executing.
I've posted a detailed guide to this problem with code examples here:
http://tpbapp.com/android-development/android-asynctask-stop-running-cancel-method/
I'm trying to use Jsoup 1.6.0 in my Android application, but for some reason it crashes. I simplified my code to:
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
public class JsoupTestActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
Document d = Jsoup.connect("http://www.google.com").get();
} catch (Exception e) {
Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG);
t.show();
}
}
}
But whenever I run the above on my phone (in USB debugging mode) or on the emulator, I get the message that my program has unexpectedly crashed--an error wasn't even caught. If I replace the contents of the try block with
Jsoup.connect("http://www.google.com");
the program works fine, so it seems like the get() method is causing the problems...
FYI, in my AndroidManifest.xml I did include
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
in the correct place, and R.layout.main is the default layout that the ADT generates when you create a new project. I'm using Android API level 7 for this project. How do I get this to work?
Try to download new version of Jsoup and paste jsoup-1.6.x.jar in libs folder from your project.
you can't do Network operations from the UI thread, so you should take the JSoup.connect() out of your onCreate() and use an ASyncTask
Hey,
So im newish to android and Im lost because although my code uses AsyncTask for it's heavy lifting I am still getting a ANR error when I run my one class. So here is the relevant peices of my code:
package com.cody.color;
import android.app.Activity;
import android.os.Bundle;
public class Play extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
System.out.println("about to start threader");
new GuiThreader().execute();
System.out.println("Threader finished");
setContentView(R.layout.colorboard_small);
}
}
package com.cody.color;
import android.os.AsyncTask;
public class GuiThreader extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
System.out.println("threader moving");
GUIdriver game = new GUIdriver();
game.play();
return null;
}
}
There aren't any problems with the code above that would cause an ANR, so most likely one of the following is happening:
You are trying to modify the user interface (UI) from doInBackground
An exception is occuring in your doInBackground
If you post the LogCat output or stacktrace when you get the error then it will be easier to identify.
welcome to the world of JAVA programming :) When you encounter an error your best tool to solve it is usually going to be a stacktrace. You need to learn how to analyze a stacktrace and also to include it in your questions...
What is a stacktrace you ask? The simplistic answer is that a stacktrace is an error message (although it contains a lot more info than only that). In case of an exception it tells the programmer WHAT happened, WHERE it happened and WHEN it happened. If you want to program in JAVA you need to get yourself quite familiar with them. I recommend you read some JAVA tutorials before diving into Android development.
As for your code, without the stacktrace I cannot say more... there is no obvious error except the fact that game.play(); looks like it might contain some changes to the UI, which are not allowed in another thread than the main thread (that's why AsyncTask has onPostExecute());