user10564330
user10564330

Reputation:

How to send Jsoup Document in an Intent?

I'm having trouble sending objects in intents. I read that gsoup is one method to accomplish this task but I haven't been able to make it work.

Here's an example. This code tries to grab the title of this stackoverflow question. It makes use of jsoup, gson, IntentService and LocalBroadcastManager. It doesn't work because it causes an error:java.lang.StackOverflowError

MainActivity:

package com.example.elk.gsonbug;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.Toast;
import com.google.gson.Gson;
import org.jsoup.nodes.Document;

public class MainActivity extends AppCompatActivity {

    private BroadcastReceiver broadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals(JsonIntentService.ACTION_GET_QUESTION_TITLE)) {
                    Document documentQuestionTitle = new Gson().fromJson(intent.getStringExtra(JsonIntentService.EXTRA_QUESTION_TITLE_DOCUMENT), Document.class);
                    String question = documentQuestionTitle.selectFirst("div#question-header > h1").text();
                    Toast.makeText(context, question, Toast.LENGTH_LONG).show();
                }
            }
        };
        LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, new IntentFilter(JsonIntentService.ACTION_GET_QUESTION_TITLE));


        JsonIntentService.startActionGetQuestionTitle(this, "https://stackoverflow.com/questions/53013644/how-to-send-jsoup-document-in-an-intent");
    }
}

JsonIntentService:

package com.example.elk.gsonbug;

import android.app.IntentService;
import android.content.Intent;
import android.content.Context;
import android.support.v4.content.LocalBroadcastManager;

import com.google.gson.Gson;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.IOException;

public class JsonIntentService extends IntentService {
    static final String ACTION_GET_QUESTION_TITLE = "com.example.elk.gsonbug.action.GET_QUESTION_TITLE";
    private static final String EXTRA_URL = "com.example.elk.gsonbug.extra.URL";
    static final String EXTRA_QUESTION_TITLE_DOCUMENT = "com.example.elk.gsonbug.extra.QUESTION_TITLE_DOCUMENT";

    public JsonIntentService() {
        super("JsonIntentService");
    }

    public static void startActionGetQuestionTitle(Context context, String url) {
        Intent intent = new Intent(context, JsonIntentService.class);
        intent.setAction(ACTION_GET_QUESTION_TITLE);
        intent.putExtra(EXTRA_URL, url);
        context.startService(intent);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            final String action = intent.getAction();
            if (action.equals(ACTION_GET_QUESTION_TITLE)) {
                final String url = intent.getStringExtra(EXTRA_URL);
                handleActionGetQuestionTitle(url);
            }
        }
    }

    private void handleActionGetQuestionTitle(String url) {
        Document documentQuestionTitle = null;
        try {
            Connection.Response responseDocumentQuestionTitle = Jsoup.connect(url)
                    .method(Connection.Method.GET)
                    .execute();
            documentQuestionTitle = responseDocumentQuestionTitle.parse();

            Intent intent = new Intent();
            intent.setAction(ACTION_GET_QUESTION_TITLE);
            intent.putExtra(EXTRA_QUESTION_TITLE_DOCUMENT, new Gson().toJson(documentQuestionTitle, Document.class));
            LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

EDIT #1

Here's a simpler example (which doesn't manifest the problem...) MainActivity calls SecondActivity which created a Person object and sends it back with gson. It works without problem: D/MainActivity: Person{name='Bob', age=33} Does this mean that something in the Document class is not compatible with gson?

MainActivity:

package com.example.elk.gsonbug2;

import android.app.Activity;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.google.gson.Gson;


public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    private static final int REQUEST_PERSON = 0;

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

        Intent intent = new Intent(this, SecondActivity.class);
        startActivityForResult(intent, REQUEST_PERSON);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_PERSON) {
            if (resultCode == Activity.RESULT_OK) {
                Person person = new Gson().fromJson(data.getStringExtra(SecondActivity.EXTRA_PERSON), Person.class);
                Log.d(TAG, person.toString());
            }
        }
    }
}

SecondActivity:

package com.example.elk.gsonbug2;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

import com.google.gson.Gson;

public class SecondActivity extends AppCompatActivity {

    static final String EXTRA_PERSON = "com.example.elk.gsonbug2.extra.PERSON";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        Intent intent = new Intent();
        Person person = new Person("Bob", 33);
        intent.putExtra(EXTRA_PERSON, new Gson().toJson(person));
        setResult(Activity.RESULT_OK, intent);
        finish();
    }

}

Upvotes: 0

Views: 165

Answers (2)

Irregular Expression
Irregular Expression

Reputation: 101

What's the purpose for sending the whole object in intent? If you need to send any big and non-primitive object from one activity to another - store the object into SQLite database, ORM or internal/external storage and send only its id with intent.

Upvotes: 0

xpland
xpland

Reputation: 3

Make the request in MainActivity, that way you don't need to worry about sending objects back and forth.

Upvotes: 0

Related Questions