尝试在Service中处理不同的方案

时间:2015-11-22 17:31:13

标签: java android multithreading service

我遇到了问题而且我没有想法如何修复它。

目标,当用户点击按钮时,根据在设置中选择的内容加载网址。

问题,我无法以正确的方式进行设置。

逻辑上(对我而言),我试图在服务中进行设置。点击按钮>服务开始> URL从" IF ELSE"加载。 问题是,我在" IF ELSE" - "必须从UI线程调用方法长度,当前推断的线程是worker。

public static class Service extends IntentService {
    public Service() {
        super("wallpaperchanger-download");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        MainActivity mainActivity;
        mainActivity = new MainActivity();

        if (mainActivity.mEditTextHashtag.length() > 2) {

            WallpaperManager wm = WallpaperManager.getInstance(this);
            int height = wm.getDesiredMinimumHeight();
            int width = wm.getDesiredMinimumWidth();

            String url = "https://source.unsplash.com/all/?" + mainActivity.mEditTextHashtag.getText() + "/" + width + "x" + height + "/";
            try {
                InputStream input = new URL(url).openStream();
                Log.v(TAG, url);
                wm.setStream(input);
                input.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            loading = false;
        }

    }
}

好的,公平的。 我创建了新的方法getPhoto();在UI线程中并将代码放在那里。然后,我调用了mainActivity.getPhoto();在服务中。 问题是,我收到错误 - "尝试调用虚方法' int android.widget.EditText.length()'在null对象引用"

关于我应该做什么的任何想法?

所有荣耀的完整代码:

package com.edip.splashwallpaper;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.app.WallpaperManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.Toast;

import java.io.InputStream;
import java.net.URL;

public class MainActivity extends android.app.Activity {

    final static String TAG = "AllInOne";
    final static int CHANGE_INTERVAL = 30 * 1000; //30 sec for testing
    static boolean loading = false;
    WallpaperManager wm;

    //Layout Views
    Switch mSwitchFixedPhoto, mSwitchControls, mSwitchSave, mSwitchPause;
    Spinner mSpinnerCategories, mSpinnerInterval;
    EditText mEditTextHashtag;
    Button mWallpaperButton;


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

        //Layout Views Initialized
        mSwitchFixedPhoto = (Switch) findViewById(R.id.sw_fixedphoto);
        mSwitchControls = (Switch) findViewById(R.id.switch_controls);
        mSwitchSave = (Switch) findViewById(R.id.switch_save);
        mSwitchPause = (Switch) findViewById(R.id.switch_pause);
        mSpinnerCategories = (Spinner) findViewById(R.id.spinner_categories);
        mSpinnerInterval = (Spinner) findViewById(R.id.spinner_interval);
        mEditTextHashtag = (EditText) findViewById(R.id.et_hashtag);
        mWallpaperButton = (Button) findViewById(R.id.btn_set_wallpaper);


        // Create an ArrayAdapter using the string array and a default spinner layout
        ArrayAdapter<CharSequence> adapterCategory = ArrayAdapter.createFromResource(this,
                R.array.categories_array, R.layout.dialog_spinner_layout);
        // Specify the layout to use when the list of choices appears
        adapterCategory.setDropDownViewResource(R.layout.dialog_spinner_layout);
        // Apply the adapter to the spinner
        mSpinnerCategories.setAdapter(adapterCategory);

        ArrayAdapter<CharSequence> adapterInterval = ArrayAdapter.createFromResource(this,
                R.array.interval_array, R.layout.dialog_spinner_layout);
        adapterInterval.setDropDownViewResource(R.layout.dialog_spinner_layout);
        mSpinnerInterval.setAdapter(adapterInterval);

        mWallpaperButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                PendingIntent pending = PendingIntent.getBroadcast(MainActivity.this,
                        666, new Intent("com.edip.splashwallpaper.CHANGE_WALLPAPTER_TIMER"),
                        PendingIntent.FLAG_CANCEL_CURRENT);

                ((AlarmManager) getSystemService(Context.ALARM_SERVICE))
                        .setRepeating(AlarmManager.RTC, System.currentTimeMillis(),
                                CHANGE_INTERVAL, pending);

            }
        });

    }

    public void getPhoto() {

        if (mEditTextHashtag.length() > 2) {

            wm = WallpaperManager.getInstance(this);
            int height = wm.getDesiredMinimumHeight();
            int width = wm.getDesiredMinimumWidth();

            String url = "https://source.unsplash.com/all/?" + mEditTextHashtag.getText() + "/" + width + "x" + height + "/";
            try {
                InputStream input = new URL(url).openStream();
                Log.v(TAG, url);
                wm.setStream(input);
                input.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            loading = false;

        } else {

            Toast.makeText(this, "Something else", Toast.LENGTH_SHORT).show();

        }

    }

    public static class Service extends IntentService {
        public Service() {
            super("wallpaperchanger-download");
        }

        @Override
        protected void onHandleIntent(Intent intent) {
            MainActivity mainActivity;
            mainActivity = new MainActivity();

            mainActivity.getPhoto();
        }
    }

    public static class AlarmReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(final Context context, Intent intent) {
            if (!loading) {
                loading = true;
                context.startService(new Intent(context, Service.class));
            }
        }
    }
}

谢谢:)

1 个答案:

答案 0 :(得分:1)

首先,你应该从不自己实例化一项活动。

其次,作为最佳做法,您的服务不应该知道您的活动,或者它有编辑文本。相反,当创建PendingIntent时,您应该发送URL以在意图内加载,如下所示:

Intent intent  = new Intent("com.edip.splashwallpaper.CHANGE_WALLPAPTER_TIMER");
intent.putExtra("USER_URL", "https://source.unsplash.com/all/?" + mEditTextHashtag.getText() + "/" + width + "x" + height + "/");
PendingIntent pending = PendingIntent.getBroadcast(MainActivity.this,
                    666, intent, PendingIntent.FLAG_CANCEL_CURRENT);

然后在您的服务中,阅读网址:

@Override 
protected void onHandleIntent(Intent intent) {
    String url = intent.getStringExtra("USER_URL");
    // ... 
}