GVKun编程网logo

android – WINDOW_SERVICE无法解析为变量(android无法解析符号)

16

本文将介绍android–WINDOW_SERVICE无法解析为变量的详细情况,特别是关于android无法解析符号的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时

本文将介绍android – WINDOW_SERVICE无法解析为变量的详细情况,特别是关于android无法解析符号的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于Android gradle无法解决:play-services-basement、Android service (一) startService vs bindService、Android Service And Bound Service 总结思维导图、Android Service 再次 unbindSrvice 时的问题的知识。

本文目录一览:

android – WINDOW_SERVICE无法解析为变量(android无法解析符号)

android – WINDOW_SERVICE无法解析为变量(android无法解析符号)

我认为WINDOW_SERVICE应该是 android.content.Context中定义的常量.

http://developer.android.com/reference/android/content/Context.html#WINDOW_SERVICE

当我在下面的代码段中使用它时,它会抛出一个错误,说它无法作为变量解析.

显示display =((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultdisplay();

这是完整的代码:

package com.commonsware.android.skeleton;

import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.*;
import android.os.Bundle;
import android.view.display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import java.io.IOException;
import java.util.List;

// ----------------------------------------------------------------------

public class SimpleBulbActivity extends Activity {
    private Preview mPreview;
    FrameLayout preview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Hide the window title.
        requestwindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
    }

    protected void onResume() {
        super.onResume();
        //Setup the FrameLayout with the Camera Preview Screen
        mPreview = new Preview(this);
        preview = (FrameLayout)findViewById(R.id.preview); 
        preview.addView(mPreview);
    }

}

// ----------------------------------------------------------------------

class Preview extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    Camera mCamera;

    Preview(Context context) {
        super(context);

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created,acquire the camera and tell it where
        // to draw.
        mCamera = Camera.open();
        try {
           mCamera.setPreviewdisplay(holder);
        } catch (IOException exception) {
            mCamera.release();
            mCamera = null;
            // Todo: add more exception handling logic here
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // Surface will be destroyed when we return,so stop the preview.
        // Because the CameraDevice object is not a shared resource,it's very
        // important to release it when the activity is paused.
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }


    private Size getoptimalPreviewSize(List<Size> sizes,int w,int h) {
        final double ASPECT_TOLERANCE = 0.05;
        double targetRatio = (double) w / h;
        if (sizes == null) return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio,ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

    public void surfaceChanged(SurfaceHolder holder,int format,int h) {
        // Now that the size is kNown,set up the camera parameters and begin
        // the preview.
        Camera.Parameters parameters = mCamera.getParameters();

        List<Size> sizes = parameters.getSupportedPreviewSizes();
        Size optimalSize = getoptimalPreviewSize(sizes,w,h);
        parameters.setPreviewSize(optimalSize.width,optimalSize.height);

        display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultdisplay();

        if(display.getRotation() == Surface.ROTATION_0)
        {
            parameters.setPreviewSize(h,w);                           
            mCamera.setdisplayOrientation(90);
        }

        if(display.getRotation() == Surface.ROTATION_90)
        {
            parameters.setPreviewSize(w,h);                           
        }

        if(display.getRotation() == Surface.ROTATION_180)
        {
            parameters.setPreviewSize(h,w);               
        }

        if(display.getRotation() == Surface.ROTATION_270)
        {
            parameters.setPreviewSize(w,h);
            mCamera.setdisplayOrientation(180);
        }

        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }

}

解决方法

尝试…
display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultdisplay();

Android gradle无法解决:play-services-basement

Android gradle无法解决:play-services-basement

突然gradle无法构建刚刚工作的相同代码!
我的项目取决于谷歌播放服务依赖项

它说 :

找不到play-services-basement.aar(com.google.android.gms:play-services-basement:15.0.1).
在以下位置搜索:
    https://jcenter.bintray.com/com/google/android/gms/play-services-basement/15.0.1/play-services-basement-15.0.1.aar

我认为aar文件被误删了谷歌

有没有人有任何想法,发生了什么?

解决方法:

在build.gradle中添加google()存储库.并检查google()是否在jcenter()之前.

Android service (一) startService vs bindService

Android service (一) startService vs bindService

service 简介

  • service 是Android的4大组件之一, 用于在后台<em>(这里指的是service不提供UI, 用户不可见)</em>执行任务.
  • service 是在UI线程上被创建, 并且在UI线程上运行的, 如果service需要执行耗时操作,那么需要自己开启线程或线程池,然后在子线程中执行.
  • service 有2种启动方式: startService & bindService <em>(也可以同时使用这2种方式)</em>

使用service VS 在其他组件中开启子线程

首先要说明的是service和thread是2个并不对等的概念, 这里之所以将它们放在一起比较, 是因为不少人在实际开发中会遇到这样的抉择: 是创建一个service去执行一个操作呢, 还是直接开启一个子线程?

service 和 thread 的区别
  • service
    1. service是Android提供的一个基础组件, 当进程中有存活的service时, 那么这个进程至少拥有Service process级别的优先级<em>(Android定义了5个级别的进程优先级)</em>. 因此这个进程退到后台后, 也不容易被回收.
    2. 当系统负载过高杀死该进程之后, 该service依然会在系统资源变得充足之后再次运行<em>(如果onStartCommand方法返回START_STICKY或者START_REDELIVER_INTENT的话)</em>. 这就意味着即使包含service的进程可能会被系统杀死, 但相应的任务依然是有机会恢复执行的,
    3. service具有高可复用性, 可以为不同的进程, 不同的应用提供服务
  • thread
    1. thread并不是Android提供的概念, 只是一个单独的执行单元, 可以用于实现负载均衡. 在Android中使用thread的一个常见情形是避免ANR.
何时使用service, 何时使用thread
  • 如果该任务的结果只在用户与其交互时有效<em>(例如界面显示时有效, 界面隐藏或销毁之后就无效了)</em>, 那么适合用thread去执行.<em>(例如在界面上显示一张远程图片, 就可以在子线程中去下载图片)</em>
  • 如果该任务在用户退到后台后仍然希望执行, 或者改任务并不直接影响到用户的交互, 那么适合使用service(通常在service中也要创建thread去执行).<em>(例如下载服务)</em>

startService VS bindService

startService 和 bindService 的简介
  • startService
    • 通过startService启动的service将在后台持续运行,直到某个组件调用stopService,或者该service自己调用stopSelf,或者因为内存不足而被系统销毁. <em>这意味着调用方通常需要管理service的生命周期</em>
    • 通过这种方式启动的Service和启动它的组件之间没有绑定关系(可以理解为游离的),因此启动它的组件被销毁了,并不会影响到service的运行
    • onStartCommand的返回值对service的生命周期的影响.(仅当service没有正常终止而是被系统销毁,此方法的返回值才会有效)
      • START_STICKY: 系统会重新创建该service,并调用onStartCommand方法,传入的intentnull.<em>(适用于需要长期存在的一些任务)</em>
      • START_NOT_STICKY: 系统不会再创建该service, 除非其他组件start它. <em>(通常建议使用它)</em>
      • START_REDELIVER_INTENT: 系统会重新创建该service,并调用onStartCommand方法,传入的intent为service销毁之前的最后一个intent. <em>(下载服务适用于此方式)</em>

<font color=red>注意: </font> 在Android 2.0以后, onStartCommand()方法默认返回START_STICKY, 通常情况下, 我们需要考虑我们的服务是否应该使用START_STICKY, 如果不是,则需要重写此方法.

  • bindService

    • bind 这种方式使得发起绑定的组件被绑定的service形成了一个client-server模式.当发起绑定的组件被销毁后, 被绑定的service也会随之销毁.<em>(前提是没有其他的组件和它绑定, 并且该service没有被start, 或者虽然被start过, 但已经执行了stopService/stopSelf 方法)</em>
    • 当绑定service的组件C被销毁后,service也会被销毁(service的onDestroy会被调用),不管组件C在销毁前是否调用了unbindService.<em>(如果没有调用unbindService,那么Logcat中会打印出android.app.ServiceConnectionLeaked异常, 不过通过MAT分析内存dump文件,可以看出 绑定service的组件以及service自身都是可以被回收的)</em>
    • 通过bindService的方式, client可以得到一个IBinder的接口, 进而可以将其转换为IInterface接口, 用于和远程service进行通信.<em>(如果client和server在同一个进程内, 那么service返回的IBinder直接提供一个返回Service引用的方法, 使用起来可能会更方便一些)</em>
    • 当被绑定的service被销毁之后,ServiceConnection.onServiceDisconnected会被调用,当系统重新创建该service之后,ServiceConnection.onServiceConnected会再次被触发
    • <font color=red>注意:</font>要支持bind, service的onBind方法必需返回一个IBinder对象, 如果返回null, 那么要绑定该service的组件提供的ServiceConnection.onServiceConnected将不会被调用,也就是说绑定会失败.<em>(注意:该service仍然会被创建,也会一直运行,直到要绑定它的那个组件销毁的时候一起销毁)</em>. 如果希望某个service不允许被任何其他组件绑定, 那么在其onBind方法中返回null就好了.
    • <font color=red>重要:</font>通过相同的Intent调用bindService方法, service的onBind方法只会被调用一次(即第一次会被调用), 对于后续的bindService调用, 系统将会直接返回上一此的IBinder.
    	// 这里比较 Intent 是否相同, 使用的是: android.content.Intent.FilterComparison.equals() 方法
    
    	// 每次 onBind 方法成功执行之后, 对应的 IntentBindRecord 会保存到 ServiceRecord 之中
    
    	// com.android.server.am.ServiceRecord
    	final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
    	            = new ArrayMap<Intent.FilterComparison, IntentBindRecord>();
    
    	// 对于bindService(Intent service, ServiceConnection conn, int flags)
    	// 如果参数 Intent 之前使用过, 那么对应的service的onBind方法不会再调用, 而是直接返回之前的IBinder
    
    • 只有当所有绑定到该service的组件都与其解绑了,onUnbind方法才会被调用.(如果onUnbind返回true,那么下次绑定service,系统创建后将不会调用onBind,而是调用onRebind,并返回之前的IBinder)
何时使用startService, 何时使用bindService
  • 如果只是要启动service去执行一个任务, 则使用startService比较合适.
  • 如果启动service之后要与它进行交互<em>(例如调用服务的方法, 甚至是client与server的双向通行)</em>, 则使用bindService比较合适.
既start又bind

通常这样做的目的是:

  1. 需要service能长时间的运行, 而不要关心启动它的组件是否被销毁. <em>start</em>
  2. 需要和service进行交互 以调用service的一些方法. <em>bind</em>
例如:实现一个DownloadService
1. startService目的: 使得 DownloadService 可以长久的在后台运行
2. bindService目的: 使用 DownloadService 提供的下载进度等Api

// 顺便说一句, 像DownloadService这样的服务, onStartCommand()方法建议返回START_REDELIVER_INTENT

此时要终止该service,需要同时具备下面2个条件:

  1. service调用了stopSelf或者某个组件调用了stopService
  2. 所有绑定到该service的组件都已解绑或者被销毁

隐式Intent的风险

之所以说通过隐式Intent启动service存在安全风险,是因为:

  • 通常调用者无法确定通过隐式Intent启动的service是哪一个(这个service甚至可能来自其他应用)
  • service在后台运行,没有用户界面.因此很难感知到这个service的存在以及它在干什么

通常建议startServicebindService使用显示Intent.并且在Manifest文件中定义service时,不应该提供<intent-filter>, export设置为false(如果没有提供<intent-filter>,那么export默认就是false)

**注意:**如果targetSdkVersion>=21的话,startService,bindService不能使用隐式Intent,否则会抛出IllegalArgumentException

ContextImpl.java
private void validateServiceIntent(Intent service) {
	if (service.getComponent() == null && service.getPackage() == null) {
		if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
			IllegalArgumentException ex = new IllegalArgumentException("Service Intent must be explicit: " + service);
			throw ex;
		} else {
			Log.w(TAG, "Implicit intents with startService are not safe: " + service
                        + " " + Debug.getCallers(2, 3));
		}
	}
}

tips

  • 使用隐式Intent, 但是限定被启动的组件在指定app中的方法:
//在使用隐式Intent的时候, 可以通过 Intent.setPackage(packagename);
//来将组件的匹配限制在某个应用内.

//限制该隐式intent只匹配自己应用内的某个组件
intent.setPackage("my package name");
  • BroadcastReceiver.onReceive(Context context, Intent intent)方法中的context是不能用来绑定service的, 因为该context是:android.app.ReceiverRestrictedContext重写了bindService方法, 并抛出异常.
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
	throw new ReceiverCallNotAllowedException("BroadcastReceiver components are not allowed to bind to services");
}

Android Service And Bound Service 总结思维导图

Android Service And Bound Service 总结思维导图

包括 started service 和 bound service。

started service 的基本概念,创建方法,生命周期等。

bound service 的基本概念,创建方法,绑定方法,生命周期等。

前端运行 service 和给用户通知响应准备在其他文档中总结。

点击查看无码高清大图:

原文出处:http://www.mcjiffy.cn/343.html

Android Service 再次 unbindSrvice 时的问题

Android Service 再次 unbindSrvice 时的问题

Android Service 未被绑定的情况下,调用 unbindService(connection) 会报错误:service Service not registered, 所以在解除绑定前要先判断连接是否处于绑定状态.

MainActivity类:

public class MainActivity extends AppCompatActivity {

    private MyService.DownloadBinder downloadBinder;

    private boolean isBind = false; //是否绑定服务

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final Button startService = (Button)findViewById(R.id.start_service);
        final Button stopService = (Button)findViewById(R.id.stop_service);
        final Button bindService = (Button)findViewById(R.id.bind_service);
        final Button unbindService = (Button)findViewById(R.id.unbind_service);

        startService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent startIntent = new Intent(MainActivity.this, MyService.class);
                startService(startIntent);
            }
        });

        stopService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent stopIntent = new Intent(MainActivity.this, MyService.class);
                stopService(stopIntent);
            }
        });

        bindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent bindIntent = new Intent(MainActivity.this, MyService.class);
                isBind = bindService(bindIntent, connection, BIND_AUTO_CREATE);   //绑定服务
            }
        });

        unbindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(isBind){ //解除绑定前要判断服务是否是绑定状态,其实此处应该还要加入 connection 是否为null 的判断
                    unbindService(connection);  //解绑服务
                    isBind = false;
                }

            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            downloadBinder = (MyService.DownloadBinder)service;
            downloadBinder.startDownload();
            downloadBinder.getProgress();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };
}

MyService 类:

public class MyService extends Service {
    private DownloadBinder mBinder = new DownloadBinder();



    public MyService() {
    }

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

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService", "onCreate execute");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService", "onStartCommand execute");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyService", "onDestroy execute");
    }

    class DownloadBinder extends Binder{
        public void startDownload(){
            Log.d("MyService", "startDownload executed");
        }

        public int getProgress(){
            Log.d("MyService", "getProgress executed");
            return 0;
        }
    }
}

关于android – WINDOW_SERVICE无法解析为变量android无法解析符号的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Android gradle无法解决:play-services-basement、Android service (一) startService vs bindService、Android Service And Bound Service 总结思维导图、Android Service 再次 unbindSrvice 时的问题等相关知识的信息别忘了在本站进行查找喔。

本文标签: