Využij akce až 30 % zdarma při nákupu e-learningu. Více informací. Zároveň je tento týden sleva až 80 % na e-learning týkající se C# .NET
Hledáme nového kolegu do redakce - 100% home office, 100% flexibilní pracovní doba. Více informací.
discount week 30 halloween
Avatar
David
Člen
Avatar
David:9.12.2019 16:23

Ahoj, po nějaké době jsem se opět vrátil k android studiu.
Zkoušel jsem funkci knihovny Jsoup. Když ji píši čistě v Javě v Intellij studiu funkce mi jede.
Chtěl bych ze stránky Wikihow vypsat obsah třídy dané názvem("cat_icon"). Jsou to názvy kapitol v levé části stránky.

Funkční kód z Intellij mám zde:

import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;

public class myjsoup {

    public static void main (String[] args) throws IOException{
        Document d=Jsoup.connect(("https://www.wikihow.com/Main-Page")).get();
        Elements ofclass = d.getElementsByClass("cat_icon");
        System.out.println(ofclass.text());
    }
}

V Android studiu však nevím kam mám tuto funkci zařadit. Podle dokumentace bych se domníval že to mám správně, jenže text se nevypíše.

Jak byste to napsali vy?

Díky

Kód z Android studia:

package com.example.jsouprun;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
//
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;


public class MainActivity extends AppCompatActivity {

    TextView Promena_TextViewTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState)  {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String ofclass;

        try {
            Document d = Jsoup.connect("https://www.wikihow.com/Main-Page").get();
            ofclass = String.valueOf(d.getElementsByClass("cat_icon"));
        } catch (IOException e) {
            ofclass = e.getMessage();
        }

        Promena_TextViewTextView = findViewById(R.id.myid);
        Promena_TextViewTextView.setText(ofclass);
    }
}
 
Odpovědět
9.12.2019 16:23
Avatar
tknette
Člen
Avatar
tknette:9.12.2019 18:55

Pokud to nevyhazuje žádnou chybu, tak stačí textView překreslit, ne?

Promena_TextViewTextView.invalidate();
 
Nahoru Odpovědět
9.12.2019 18:55
Avatar
Odpovídá na David
Matúš Olejník:9.12.2019 20:20

Ahoj, v tomto prípade je nutné aby samotné parsovanie bežalo mimo hlavného UI vlákna.

Takže buď použiješ napr. triedu Executor alebo zdedíš triedu Thread a vo výsledku spustíš parsovanie v novom vlákne

alebo môžeš použiť AsyncTask kde v metóde doInBackground vykonáš parsovanie a v metóde onPostExecute nastavenie výsledku do tvojho TextFieldu, prípade v metóde onProgressUpdate môžeš napr. updatovať progres bar, viacej tu -> https://developer.android.com/…os/AsyncTask

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    private Button doParseButton;

    private TextView outputTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        outputTextView = findViewById(R.id.outputTextView);

        doParseButton = findViewById(R.id.doParseButton);
        doParseButton.setOnClickListener(
                v -> new ParseAsyncTask(
                        result -> outputTextView.setText(result)
                ).execute()
        );
    }
}

import android.os.AsyncTask;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.IOException;

public class ParseAsyncTask extends AsyncTask<Void, Void, String> {

    //alebo Consumer<String> ktorý je od vyššieho API
    public interface Callback {
        void onPostExecuteEx(String result);
    }

    private Callback callback;

    public ParseAsyncTask(Callback callback) {
        this.callback = callback;
    }

    protected String doInBackground(Void ... urls) {
        String ofclass;
        try {
            Document d = Jsoup.connect("https://www.wikihow.com/Main-Page").get();
            ofclass = String.valueOf(d.getElementsByClass("cat_icon"));
        } catch (IOException e) {
            ofclass = e.getMessage();
        }
        return ofclass;
    }

    protected void onProgressUpdate(Void... progress) {
        System.out.println("Working...");
    }

    protected void onPostExecute(String result) {
        System.out.println("Async task completed.");
        if (callback != null){
            callback.onPostExecuteEx(result);
        }
    }
}

Nad názvami som veľmi nerozmýšlal je to len ukážka. A samozrejme v manifeste musí byť povolenie k internetu

<uses-permission android:name="android.permission.INTERNET" />
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět
9.12.2019 20:20
/* I am not sure why this works but it fixes the problem */
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
David
Člen
Avatar
David:9.12.2019 22:08

Díky, mám se ještě co učit :-)

 
Nahoru Odpovědět
9.12.2019 22:08
Avatar
David
Člen
Avatar
Odpovídá na Matúš Olejník
David:15.12.2019 19:00

Ten kód mi už fungoval správně a nijak jsem ho neměnil. Teď se tam ale ukazuje ;-( :

*FAILURE: Build failed with an exception.

  • What went wrong:

Execution failed for task ':app:mergeDe­bugJavaResource'.

A failure occurred while executing com.android.bu­ild.gradle.in­ternal.tasks.Wor­kers$ActionFa­cade

> More than one file was found with OS independent path 'META-INF/CHANGES'

  • Try:

Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

BUILD FAILED in 0s
25 actionable tasks: 1 executed, 24 up-to-date*

 
Nahoru Odpovědět
15.12.2019 19:00
Avatar
Odpovídá na David
Matúš Olejník:19.12.2019 22:35

Sorry nemal som veľmi čas. S gradlom skoro vôbec nerobím takže googlim tak ako by si aj ty mohol a väčšinou odporúčajú excludnuť ten súbor z buildu

https://stackoverflow.com/…nder-problem

https://stackoverflow.com/…-inf-license

Nahoru Odpovědět
19.12.2019 22:35
/* I am not sure why this works but it fixes the problem */
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 6 zpráv z 6.