使用Android中的服务类在弹出窗口中显示ListView

时间:2017-05-14 13:02:08

标签: android android-service android-popupwindow

我想使用服务类在弹出窗口中显示自定义列表视图。此列表从数据库中获取数据并在活动中正常工作,但不在弹出窗口中。以下是我的代码。任何帮助将不胜感激。

这是我的服务类:

public class PopupService extends Service{

    final static String URL = "https://billspill.com/json.php";
    private WindowManager mWindowManager;
    private View popupview;

    public PopupService() {
    }

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

    @Override
    public void onCreate() {
        popupview  = LayoutInflater.from(this).inflate(R.layout.popup, null);
        //Add the view to the window.
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.TOP | Gravity.START;  
        params.x = 0;
        params.y = 100;

        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(popupview, params);
        Button close = (Button)popupview.findViewById(R.id.dismiss);
        close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopSelf();

            }
        });

        ListView lv = (ListView)popupview.findViewById(R.id.pager);
        new Downloader(this,lv,URL).execute();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (popupview != null) mWindowManager.removeView(popupview);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_NOT_STICKY;
    }

下面是我的Downloader类,它扩展了AsyncTask。此Downloader类从DataParser类调用DataParser方法,该方法进一步调用Adapter类以将数据膨胀到列表中。这三个类在一个活动中运行良好,但是当我在我的服务中调用Downloader时,应用程序崩溃了。我认为从服务类传递Downloader中的Context存在问题。

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

    Context ctx;
    ListView lv;
    ProgressDialog pd;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pd=new ProgressDialog(ctx);
        pd.setTitle("Retrive");
        pd.setMessage("Retrieving....please wait");
        pd.show();
    }

    @Override
    protected void onPostExecute(String jsonData) {
        super.onPostExecute(jsonData);
        pd.dismiss();
        if(jsonData==null)
        {
            Toast.makeText(ctx,"Unsuccessfull,No data Retrieved",Toast.LENGTH_SHORT).show();
        }
        else {
            DataParser parser = new DataParser(ctx,jsonData,lv);

            parser.execute();
        }
    }

    private String downloadData(){

        HttpURLConnection con = Connector.connect(urlAddress);
        if(con==null) {
            Toast.makeText(ctx,"Connection is null",Toast.LENGTH_LONG).show();
        }

        try{
            InputStream is = new BufferedInputStream(con.getInputStream());
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String line;
            StringBuffer jsonData= new StringBuffer();

            while ((line=br.readLine())!=null)
            {

                jsonData.append(line+"/n");
            }
            br.close();
            is.close();
            return jsonData.toString();

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

        return null;
    }

    public Downloader(Context ctx, ListView lv, String urlAddress) {
        this.ctx = ctx;
        this.lv = lv;

        this.urlAddress = urlAddress;
    }

    String urlAddress;

    @Override
    protected String doInBackground(Void... params) {
        return downloadData();
    }

崩溃的开始:

 --------- beginning of crash
05-14 18:58:00.694 10664-10664/com.billspillsmoothshopping.android E/AndroidRuntime: FATAL EXCEPTION: main
 Process: com.billspillsmoothshopping.android, PID: 10664
 java.lang.RuntimeException: Unable to create service com.billspillsmoothshopping.android.PopupService: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2771)
     at android.app.ActivityThread.access$1800(ActivityThread.java:151)
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1386)
     at android.os.Handler.dispatchMessage(Handler.java:102)
     at android.os.Looper.loop(Looper.java:135)
     at android.app.ActivityThread.main(ActivityThread.java:5254)
     at java.lang.reflect.Method.invoke(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:372)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)
  Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
     at android.view.ViewRootImpl.setView(ViewRootImpl.java:584)
     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:282)
     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
     at android.app.Dialog.show(Dialog.java:298)
     at com.billspillsmoothshopping.android.m_MySQL.CompareDownloader.onPreExecute(CompareDownloader.java:32)
     at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:591)
     at android.os.AsyncTask.execute(AsyncTask.java:539)
     at com.billspillsmoothshopping.android.PopupService.onCreate(PopupService.java:81)
     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2761)
     at android.app.ActivityThread.access$1800(ActivityThread.java:151) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1386) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:135) 
     at android.app.ActivityThread.main(ActivityThread.java:5254) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:372) 

1 个答案:

答案 0 :(得分:0)

您无法附加弹出窗口,其中包含您必须传递实际活动上下文的服务,而不是服务上下文,这是您收到此错误的原因。

我建议你只使用asynctask https://developer.android.com/reference/java/lang/Object.html来获取数据并在服务不那么必要时显示它,如果在下载数据后使用服务太必要,则使用广播接收器将此数据传递给某些活动https://developer.android.com/reference/android/content/BroadcastReceiver.html然后显示弹出窗口。 希望能帮助到你。 附: &#34;我们将服务用于长时间运行的任务,并且没有附加UI,如播放音频,从服务器等下载大数据。&#34;