Android Studio JSoup 服务

Android Studio JSoup Service

我 运行 Android Studio 2.3.2,我想制作一个应用程序,通过服务检查网站上的字符串。在没有后台服务 运行ning 的情况下使用 JSoup 库正常执行此操作工作正常,但将其作为服务尝试会在 LogCat 中出现错误并且无法正常工作。

public class BackgroundCheck extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String myurl = "http://s503426938.online.de/untis/Heute/subst_001.htm";
        try {
            // Connect to the web site
            Document document = Jsoup.connect(myurl).get();
            Element innerTable = document.getElementsByClass("mon_list").first();
            Elements rows = innerTable.select("tr");

            for (Element row : rows) {
                Elements cells = row.select("td");
                for (Element cell : cells) {
                    if (cell.className().equals("list")) {
                        if (cell.text().contains("10A")){
                            int notifID = 33;
                            int color = getResources().getColor(R.color.colorAccent);
                            long[] pattern = {0, 300, 200, 300};
                            PendingIntent settingsIntent = null;
                            String text = "es fällt bald etwas aus!";
                            NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(BackgroundCheck.this)
                                    .setSmallIcon(R.drawable.ic_notifications_black_24dp)
                                    .setContentTitle("Vertretungsplan")
                                    .setContentText(text)
                                    .setColor(color)
                                    .addAction(new NotificationCompat.Action(R.drawable.ic_menu_manage, "Settings", settingsIntent))
                                    .setLights(color, 500, 500)
                                    .setDefaults(Notification.DEFAULT_SOUND)
                                    .setVibrate(pattern);

                            Notification notification = mBuilder.build();
                            Toast.makeText(BackgroundCheck.this,"10A",Toast.LENGTH_SHORT).show();
                            NotificationManagerCompat.from(BackgroundCheck.this).notify(notifID, notification);
                        }
                    }
                }
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }






Toast.makeText(BackgroundCheck.this,"Test",Toast.LENGTH_SHORT).show(); //Works Fine
        Log.d("Vertretungsplan", "Checked: String");
        stopSelf();


        return super.onStartCommand(intent, flags, startId);
    }
}

在我的 MainActivity 中,我将这些行添加到 OnCreate 方法中,以便在启动应用程序后创建后台服务 运行:

AlarmManager alarmManager = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
        Intent check = new  Intent(MainActivity.this, BackgroundCheck.class);
        PendingIntent startServicependingIntent = PendingIntent.getService(MainActivity.this,0,check,0);

Calendar calendar = Calendar.getInstance();
int intervall  = 1000*60;
calendar.setTimeInMillis(System.currentTimeMillis() + intervall);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),intervall,startServicependingIntent);`

现在 Logcat 在尝试从 table 中的服务器获取字符串时抛出以下错误:

> 06-11 19:51:45.639 18293-18293/org.ddnss.jojeker.vertretungsplan D/Vertretungsplan: Checked: String
06-11 19:52:45.617 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err: android.os.NetworkOnMainThreadException
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:86)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at java.net.InetAddress.getAllByName(InetAddress.java:752)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.Network.resolveInetAddresses(Network.java:29)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:187)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:156)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:98)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:346)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:329)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:247)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:126)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:439)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:424)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:178)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at org.jsoup.helper.HttpConnection.get(HttpConnection.java:167)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at org.ddnss.jojeker.vertretungsplan.BackgroundCheck.onStartCommand(BackgroundCheck.java:35)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3366)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.app.ActivityThread.-wrap21(ActivityThread.java)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1612)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.os.Looper.loop(Looper.java:154)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6236)
06-11 19:52:45.619 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
06-11 19:52:45.619 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
06-11 19:52:45.619 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)

通常我使用 AsyncTask 来执行 JSoup 的操作,但我认为这不是必需的服务。我用 Toast 来确保我没有犯任何基本错误。 所以我的问题是:这是通过 JSoup 获取数据即服务的 "right" 方式,还是我在这种情况下使用它做错了什么。 是否有其他更易于使用的库,或者 JSoup 是此类工作的正确选择?

先谢谢你了!

您仍然需要生成一个线程。根据 Android Services 文档:

Caution: A service runs in the main thread of its hosting process; the service does not create its own thread and does not run in a separate process unless you specify otherwise. If your service is going to perform any CPU-intensive work or blocking operations, such as MP3 playback or networking, you should create a new thread within the service to complete that work.

堆栈跟踪中也提到了这个问题:

W/System.err: android.os.NetworkOnMainThreadException