无法在服务

时间:2016-07-22 05:13:06

标签: android android-service findviewbyid

我正在做一个应用程序,我应该使用服务在某段时间内打开一个PopUpwindow。我通过将弹出窗口代码保存在其他活动中作为方法并在服务中调用它来尝试它。但它最终徒劳无功。所以我已经将所有popupWindow代码复制到服务这里我不能使用findViewById。

我的服务代码如下

public class TimeService extends Service {
View layout;
LayoutInflater inflater;
public PopupWindow pw;
private RadioGroup options_group;
private RadioButton option_button;
Button submit_popup,close_popup;

// constant
public static final long NOTIFY_INTERVAL = 10 * 10000; // 100 seconds

// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    // cancel if already existed


    if (mTimer != null) {
        mTimer.cancel();

    } else {
        // recreate new
        mTimer = new Timer();
    }
    // schedule task
    mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}

class TimeDisplayTimerTask extends TimerTask {

    @Override
    public void run() {
        // run on another thread
        mHandler.post(new Runnable() {

            @Override
            public void run() {
                // display toast
                try {

                    inflater = (LayoutInflater) TimeService.this.
                            getSystemService(Context.LAYOUT_INFLATER_SERVICE);

                    layout = inflater.inflate(R.layout.layout_popup, (ViewGroup) findViewById(R.id.popup_1));

                    pw = new PopupWindow(layout, 300, 370, true);
                    pw.showAtLocation(layout, Gravity.CENTER, 0, 0);

                    submit_popup = (Button) layout.findViewById(R.id.popup_submit);
                    close_popup = (Button) layout.findViewById(R.id.popup_cancel);
                    options_group=(RadioGroup) layout.findViewById(R.id.radioGroup);

                    submit_popup.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            pw.dismiss();
                        }
                    });
                    submit_popup.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            int selectedId=options_group.getCheckedRadioButtonId();
                            option_button=(RadioButton) layout.findViewById(selectedId);

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

            }

        });
    }


}
}

我收到错误

 layout = inflater.inflate(R.layout.layout_popup, (ViewGroup) findViewById(R.id.popup_1));

并且错误是无法解析方法findViewbyId(int)。

请帮我解释一下代码。我做错了什么。

提前致谢。

我尝试过使用代码

layout = inflater.inflate(R.layout.layout_popup, null);

我收到错误或堆栈跟踪如下

 07-22 01:17:39.789 940-957/system_process W/WindowManager: Attempted to add window with token that is not a window: null.  Aborting.
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err:     at android.view.ViewRootImpl.setView(ViewRootImpl.java:562)
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err:     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:282)
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err:     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err:     at android.widget.PopupWindow.invokePopup(PopupWindow.java:1104)
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err:     at android.widget.PopupWindow.showAtLocation(PopupWindow.java:933)
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err:     at android.widget.PopupWindow.showAtLocation(PopupWindow.java:897)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err:     at highski.developers.cflash.service.TimeService$TimeDisplayTimerTask$1$override.run(TimeService.java:85)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err:     at highski.developers.cflash.service.TimeService$TimeDisplayTimerTask$1$override.access$dispatch(TimeService.java)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err:     at highski.developers.cflash.service.TimeService$TimeDisplayTimerTask$1.run(TimeService.java:0)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err:     at android.os.Looper.loop(Looper.java:135)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5254)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err:     at java.lang.reflect.Method.invoke(Method.java:372)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

5 个答案:

答案 0 :(得分:1)

在第二个参数中传递空值

  layout = inflater.inflate(R.layout.layout_popup, (ViewGroup) findViewById(R.id.popup_1));

 layout = inflater.inflate(R.layout.layout_popup, null);

<强>更新

 private Handler mHandler;

@Override
public void onCreate() {
    mHandler = new Handler(Looper.getMainLooper());
    //... do like above and remove perivous updated 
}

答案 1 :(得分:1)

你不能直接在服务内部进行更改,而是使用广播接收器和意图过滤器来通知你的活动/片段并从那里更新

如何为工作服务 see how service works

有些人使用reference onservices

http://www.vogella.com/tutorials/AndroidServices/article.html

https://androidexperinz.wordpress.com/2012/02/14/communication-between-service-and-activity-part-1/

答案 2 :(得分:0)

您需要使用Handler

private Handler handler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        if (msg.what == 0) {
            // add your code here.
        }
        return false;
    }
});

在ua Run()方法中添加调用处理程序。

handler.sendEmptyMessage(0);

一切顺利。

答案 3 :(得分:0)

请参阅此处的答案

Show dialog alert from a non-activity class in android

问题是“You can show AlertDialogs ,dialog or Popupwindow from your Service Activity only”。

虽然从接收器或服务显示对话框不是一个好主意(最好是使用通知),但如果你想这样做,你可以创建一个Activity as dialog and show

答案 4 :(得分:0)

AlertDialog应由具有窗口的Activity管理,因为Service是非UI组件,因此您无法在服务中显示对话框,否则应用程序将崩溃:

  

引起:android.view.WindowManager $ BadTokenException:无法添加窗口 - 令牌null不适用于应用程序

     

在android.app.Dialog.show(Dialog.java:325)

您可以通过两种方式在服务中显示对话框:

1,启动对话框主题活动,并在此活动的onCreate方法中显示一个对话框。

android:theme="@android:style/Theme.Holo.Light.Dialog"

OR

2,将对话框设置为系统警报:

    AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
    builder.setTitle("title")
           .setMessage("message");
    AlertDialog dialog = builder.create();
    // set the dialog as system alert
    dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    dialog.show();