A Sweet Juice plugin has two parts:

  1. Go side — exposes a friendly API and calls core.CallNativePlatform to reach native code.
  2. Native side — implements SweetJuicePlugin, registers widget factories, and handles actions.

Go-side plugin

package myplugin

import (
    "encoding/json"
    "github.com/sweet-juice/sweetjuice/core"
)

type Plugin struct {
    app *core.Application
}

func NewPlugin() *Plugin {
    return &Plugin{}
}

func (p *Plugin) Init(app *core.Application) error {
    p.app = app
    // Register native callbacks if needed
    app.RegisterNativeMethod("myplugin:result", func(args []json.RawMessage) (interface{}, error) {
        // handle result from native side
        return map[string]string{"status": "ok"}, nil
    })
    return nil
}

func (p *Plugin) DoSomething(input string) (string, error) {
    payload, _ := json.Marshal(map[string]string{"input": input})
    return core.CallNativePlatform("myplugin:doSomething", payload), nil
}

Native-side plugin (Android)

package com.sweetjuice.pkg.myplugin;

import android.content.Context;
import com.sweetjuice.plugin.SweetJuicePlugin;
import org.json.JSONObject;
import org.json.JSONException;

public class MyPlugin implements SweetJuicePlugin {
    private Context mContext;

    @Override
    public String getDomain() { return "myplugin"; }

    @Override
    public void onAttach(Context context) {
        this.mContext = context;
    }

    @Override
    public String handleAction(String action, String jsonArgsPayload) {
        try {
            JSONObject args = new JSONObject(jsonArgsPayload);
            if ("doSomething".equals(action)) {
                String input = args.optString("input", "");
                // do native work
                return "{\"result\":\"" + input + "\"}";
            }
            return "{\"error\":\"Unknown action\"}";
        } catch (JSONException e) {
            return "{\"error\":\"" + e.getMessage() + "\"}";
        }
    }
}

Register the plugin

Add the plugin to SweetJuiceApplication:

registerPlugin(new com.sweetjuice.pkg.myplugin.MyPlugin());

Widget factories

If your plugin renders UI, implement SweetJuiceWidgetFactory:

public class MyWidgetFactory implements SweetJuiceWidgetFactory {
    @Override
    public String getType() { return "myplugin:widget"; }

    @Override
    public View createView(Context ctx, JSONObject node, ViewGroup parent) {
        return new TextView(ctx);
    }

    @Override
    public void updateView(View view, JSONObject node) {
        // update view from node props
    }
}

Return the factory from getWidgetFactories() in your plugin.