2022年最新版Android安卓面试题+答案精选(每日20题,持续更新中)【七】

2022年最新版Android安卓面试题+答案精选(每日20题,持续更新中)【七】_第1张图片

前言

写在前面:首先是不一次性放出来的原因:资料来之不易,希望大家好好珍惜,每天花一段时间细细的消化这些题目,其次希望大家在阅读题目的时候最好跟着书或者代码一起阅读、一起敲,做到熟稔于心,信手拈来,这样面试的时候才能展现你最自信的一面。

121、Android中的下标和上标字符串

答案:

((TextView)findViewById(R.id.text)).setText(Html.fromHtml("X2"));

122、Android Studio找不到Aapt

答案:

Aapt是一个32位应用程序。我正在运行ubuntu 64位。我需要一些其他库。我所做的第一件事是从12.10更新到13.04。它破坏了铬,但这应该有所帮助。

为了使aapt正常工作(这也解决了我在avd上的问题),只需运行以下两个命令:

sudo apt-get install lib32stdc++6
sudo apt-get install lib32z1

123、从Android发送JSON HTTP POST请求

答案:

使用POST发布参数:

URL url;
URLConnection urlConn;
DataOutputStream printout;
DataInputStream  input;
url = new URL (getCodeBase().toString() + "env.tcgi");
urlConn = url.openConnection();
urlConn.setDoInput (true);
urlConn.setDoOutput (true);
urlConn.setUseCaches (false);
urlConn.setRequestProperty("Content-Type","application/json");   
urlConn.setRequestProperty("Host", "android.schoolportal.gr");
urlConn.connect();  
//Create JSONObject here
JSONObject jsonParam = new JSONObject();
jsonParam.put("ID", "25");
jsonParam.put("description", "Real");
jsonParam.put("enable", "true");

你错过的部分在以下内容中,即如下。

// Send POST output.
printout = new DataOutputStream(urlConn.getOutputStream ());
printout.writeBytes(URLEncoder.encode(jsonParam.toString(),"UTF-8"));
printout.flush ();
printout.close ();

其余的事情你都可以做到。

124、我们可以通过打开下载文件夹吗?意图?

答案:

您可以使用以下内容显示最近的下载活动 Intent

startActivity(new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS));

自API 9起可用

125、如何在Android Lollipop上声明扩展高度的工具栏/操作栏?

答案:

您需要使用新的工具栏小部件来实现此目的。工具栏具有特殊的处理方式,因为它声明了用于按钮(和操作)的空间的最小高度。

在下面的示例中,我们将高度设置为128dp(规范中定义为56dp + 72dp),但将其保留android:minHeight为标准值actionBarSize(通常为56dp)。这意味着按钮和动作被限制为垂直放置在顶部56dp中。然后,我们可以使用android:gravity将标题放置在底部。


如果您使用的是AppCompat,请更改声明以改为使用android.support.v7.widget.Toolbar并使用其属性。

126、如何使用可用的隐藏API和内部API构建Android SDK?

答案:

我找到了这个:http : //skillsmatter.com/podcast/os-mobile-server/hidden-api dunno它将持续多长时间

Android SDK中的官方API通常对于大多数普通应用程序就足够了。但是,有时在某些情况下,开发人员需要访问未在官方API中发布的内部系统服务,API和资源。幸运的是,这些API仍然可以通过一些巧妙的技巧获得,并且在基于Android的基础上开发新的创新解决方案时通常非常有用。在本课程中,您将学习如何访问和使用这些隐藏和受保护的API,它们的使用限制以及如何在多个供应商的设备和Android版本之间以安全和可控制的方式使用它们的一些技巧。观众将看到几个通常无法使用Android进行的高级演示。期待一个相当高级的会议,其中包含有关Android平台内部知识的大量见解。

127、Android Studio Google JAR文件导致GC开销限制超出错误

答案:

认为有一种单独的方法可以提高Dexing操作的堆限制。将此添加到文件的android闭包中build.gradle:

dexOptions {
    javaMaxHeapSize "4g"
}

128、Android下载二进制文件问题

答案:

我不知道这是否是唯一的问题,但是你在其中遇到了典型的Java故障:你没有指望总是允许read()返回的字节数少于你要求的字节数。因此,你的读取可能会少于1024个字节,但是你的写入操作始终会精确地写出1024个字节,其中可能包括上一个循环迭代中的字节。

更正为:

 while ( (len1 = in.read(buffer)) > 0 ) {
         f.write(buffer,0, len1);
 }

也许更高的延迟网络或Android上3G的较小数据包大小加剧了这种影响?

129、Android中项目上的自定义ListView点击问题

答案:

问题是Android不允许你选择列表元素上具有可聚焦元素的列表项。我修改了列表项上的复选框,使其具有如下所示的属性:

android:focusable="false"

现在,我的包含复选框的列表项(也适用于按钮)在传统意义上是“可选的”(它们亮起,你可以单击列表项中的任何位置,并且将触发“ onListItemClick”处理程序,等等)。

编辑:作为一个更新,一个评论者提到“只是一个注释,在更改按钮的可见性之后,我不得不再次以编程方式禁用焦点。”

130、限制Android EditText中的小数位数

答案:

这是一个示例InputFilter,它仅允许在小数点前最多4位,在小数点后最多1位。

价值观是允许的EditText:555.2,555,0.2

价值观是的EditText块:55555.2,055.2,555.42

        InputFilter filter = new InputFilter() {
        final int maxDigitsBeforeDecimalPoint=4;
        final int maxDigitsAfterDecimalPoint=1;

        @Override
        public CharSequence filter(CharSequence source, int start, int end,
                Spanned dest, int dstart, int dend) {
                StringBuilder builder = new StringBuilder(dest);
                builder.replace(dstart, dend, source
                        .subSequence(start, end).toString());
                if (!builder.toString().matches(
                        "(([1-9]{1})([0-9]{0,"+(maxDigitsBeforeDecimalPoint-1)+"})?)?(\\.[0-9]{0,"+maxDigitsAfterDecimalPoint+"})?"

                        )) {
                    if(source.length()==0)
                        return dest.subSequence(dstart, dend);
                    return "";
                }

            return null;

        }
    };

    mEdittext.setFilters(new InputFilter[] { filter });

131、Android / Java-日期差异(天)

答案:

并不是真正可靠的方法,最好使用JodaTime

  Calendar thatDay = Calendar.getInstance();
  thatDay.set(Calendar.DAY_OF_MONTH,25);
  thatDay.set(Calendar.MONTH,7); // 0-11 so 1 less
  thatDay.set(Calendar.YEAR, 1985);

  Calendar today = Calendar.getInstance();

  long diff = today.getTimeInMillis() - thatDay.getTimeInMillis(); //result in millis

这是一个近似值…

long days = diff / (24 * 60 * 60 * 1000);

要从字符串中解析日期,你可以使用

  String strThatDay = "1985/08/25";
  SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
  Date d = null;
  try {
   d = formatter.parse(strThatDay);//catch exception
  } catch (ParseException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } 


  Calendar thatDay = Calendar.getInstance();
  thatDay.setTime(d); //rest is the same....

但是,由于你确定日期格式Integer.parseInt(),因此也可以在子字符串上执行操作以获取其数字值。

132、如何在Android中向HTTP GET请求添加参数?

答案:

我使用NameValuePair和URLEncodedUtils列表创建所需的url字符串。

protected String addLocationToUrl(String url){
    if(!url.endsWith("?"))
        url += "?";

    List params = new LinkedList();

    if (lat != 0.0 && lon != 0.0){
        params.add(new BasicNameValuePair("lat", String.valueOf(lat)));
        params.add(new BasicNameValuePair("lon", String.valueOf(lon)));
    }

    if (address != null && address.getPostalCode() != null)
        params.add(new BasicNameValuePair("postalCode", address.getPostalCode()));
    if (address != null && address.getCountryCode() != null)
        params.add(new BasicNameValuePair("country",address.getCountryCode()));

    params.add(new BasicNameValuePair("user", agent.uniqueId));

    String paramString = URLEncodedUtils.format(params, "utf-8");

    url += paramString;
    return url;
}

133、布隆过滤器或cuckoo-hashing?

答案:

Bloom过滤器和Cuckoo过滤器在类似的情况下使用,但是通常有很多差异,这些差异通常会确定哪个是更好的选择。

布隆过滤器在数据库引擎内部使用,尤其是Apache Cassandra。正如其他张贴者所说,其原因是为了减少慢速设置操作的成本。基本上,任何高成本的“这样做可能或肯定不存在”操作都可以使用Bloom过滤器来减少已完成检查的次数。

如今的SaaS模型的另一个常见示例是具有每次通话费用的远程REST服务。任何带有二进制答案的API调用(例如“此地址是否无效”)都可以使用布隆过滤器消除90%以上的重复查询!请注意,由于Bloom和Cuckoo过滤器具有误报,因此它们对于逆运算“此地址有效”无效。

要记住的重要一点是,Bloom和Cuckoo过滤器没有误报。这使得这些过滤器可用于诸如“肯定不是或不是垃圾邮件”之类的检查,但不适用于误报不可接受的操作(如检查用户权限)。在这方面,它们可以在概念上被视为与高速缓存相反。布卢姆/布谷鸟过滤器和高速缓存都主要用于降低具有布尔答案的昂贵操作的成本,但高速缓存没有误报,而布卢姆/杜鹃没有误报。

杜鹃/花朵之间的显着差异包括:

组合。只要使用相同的参数创建Bloom过滤器,就可以有效地合并它们。既快速又几乎没有带宽。这就是为什么您看到它们在大规模分布式系统中频繁使用的原因,因此交换Bloom过滤器的速度很快。布谷鸟过滤器不易组合,因此在这种情况下使用率会降低。

误报率。布谷鸟过滤器更节省空间。这两种结构的许多用例都集中在底层网络上。在弱硬件上,对于相同的误报率,杜鹃过滤器的效率提高约40%可能很重要。使用c ++的参考实现对每个存储桶中的项目进行排序,以节省更多空间,并利用存储桶中项目的位置存储较小的指纹。我稍后会提到的其他库(包括我的库)似乎都没有这样做。如果有人使用我的库,我可以添加它:)。

恒定的误报率。布隆过滤器超出设计尺寸时,其误报率渐近恶化。您可以永远插入项目,但最终您的误报率将接近100%。基于Cuckoo散列的Cuckoo过滤器具有一定的设置能力,实际插入将失败。重复插入非随机项目哈希值可能会导致布谷鸟过滤器插入失败,可能远远超出其设计的填充水平。

速度。这是主观的,并且在很大程度上取决于硬件,但是在一般情况下(以我的经验),布谷鸟过滤器通常更快。大多数布隆过滤器设计都会运行一次哈希函数两次。特别是在使用安全哈希函数时,与仅对插入项哈希一次的Cuckoo过滤器相比,这可能是一个很大的障碍。我看过的代码对Bloom和Cuckoo过滤器使用了各种哈希函数。Google的Guava Bloom使用Murmur3,许多其他实现使用SHA1或其他方式。如果可以为您的用例利用哈希冲突,请确保该库使用安全哈希。重要的是要知道,布隆过滤器的插入时间大致恒定,而布谷鸟过滤器的插入时间则是平均时间。随着布谷鸟过滤器进入容量的百分之几之内,插入速度会大大降低。即使这样,

灵活性。布隆过滤器仅支持插入和包含。布谷鸟过滤器还支持删除和有限计数。在参考设计中,布谷鸟过滤器可以确定插入项目的次数,最多7次。布隆过滤器只能确定是/否。布谷鸟过滤器还支持删除插入的项目,与Bloom相比,在很多用例中都有很大的好处。使用Bloom过滤器时,由于您无法删除旧项目,因此在“满”(估计误报率超过阈值)时从头开始重新创建过滤器是相当标准的。请注意,当插入开始失败时,使用Cuckoo过滤器仍会重建过滤器,因此根据使用情况,这可能是没有意义的。在某些情况下,布谷鸟过滤器更有用,因为您可以删除项目以使其保持在过滤器限制之内,而不用重建。

支持。布谷鸟过滤器是新的,稳定的库对于许多语言都不存在。

Bloom过滤器的最大优点是,它们在大多数语言中都具有更成熟的库支持。科学家还可以更好地理解布隆过滤器背后的数学原理。布谷鸟过滤器的大多数特性已根据经验确定,而布隆过滤器具有坚实的数值基础。这不包括用于实时系统和关键系统的Cuckoo过滤器,这些过滤器必须对其性能进行验证,即使实验证据表明Cuckoo过滤器在大多数情况下的性能也更好。

Shameless Plug:我是Java的Cuckoo过滤器库的开发人员。CuckooFilter4J。它缺少本文中使用的存储桶半排序,因此空间效率略低于参考实现。在项目自述文件中,我具有我所知道的其他实现的链接。哪种结构更好取决于您的用例,但主要取决于您的语言是否存在可靠的Cuckoo过滤器实现。

在生产中使用布谷鸟/布鲁姆滤清器之前,您绝对应该查看源代码。在编写我自己的库之前,我通读了各种库。由于32位底层数组或明显的性能问题,它们中的许多都有静默的大小限制。多数测试为零。Google的Guava Bloom实施迄今为止具有最佳的代码质量和测试(并支持64位数组限制)。Guava Bloom的唯一缺点是它没有使用安全哈希函数的选项,并且不是多线程的。

在生产系统中,您可能需要多线程以提高速度。番石榴绽放的答案是为每个线程创建不同的过滤器,并偶尔合并它们。由于无法合并Cuckoo过滤器,因此我在Cuckoo过滤器库中添加了并发线程。我知道的另一个线程不是线程安全的或不是并发的。

134、如何使用毕加索加载布局背景

答案:

您可以使用毕加索的目标:

         Picasso.with(this).load("http://imageUrl").into(new Target() {
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
               mYourLayout.setBackground(new BitmapDrawable(bitmap));
            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {

            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {

            }
        });

更新

正如@BladeCoder在评论中提到的那样,毕加索对目标对象的引用很弱,因此很可能会被垃圾回收。

因此,在杰克·沃顿就其中一个问题发表评论之后,我认为这可能是一个不错的选择:

  CustomLayout mCustomLayout = (CustomLayout)findViewById(R.id.custom_layout)
  Picasso.with(this).load("http://imageUrl").into(mCustomLayout);

CustomLayout.java:

public class CustomLayout extends LinearLayout implements Target {

    public CustomLayout(Context context) {
        super(context);
    }

    public CustomLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        setBackground(new BitmapDrawable(getResources(), bitmap));
    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {
        //Set your error drawable
    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {
        //Set your placeholder
    }
}

135、Android中的可点击小部件

答案:

首先,添加带有常量的静态变量。

public static String YOUR_AWESOME_ACTION = "YourAwesomeAction";

然后,你需要先将动作添加到意图中,然后再将意图添加到未决意图中:

Intent intent = new Intent(context, widget.class);
intent.setAction(YOUR_AWESOME_ACTION);

(其中widget.class是你的AppWidgetProvider的类,当前的类)

然后,你需要使用getBroadcast创建一个PendingIntent

PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

在窗口小部件中为可点击的视图设置onClickPendingIntent

remoteView.setOnClickPendingIntent(R.id.widgetFrameLayout, pendingIntent);

接下来,在同一类中重写onReceive方法:

@Override
public void onReceive(Context context, Intent intent) {
 super.onReceive(context, intent);

然后通过在onReceive方法中查询为你的操作返回的意图来响应你的按钮按下:

if (intent.getAction().equals(YOUR_AWESOME_ACTION)) {
   //do some really cool stuff here
}

那应该做到的!

136、在Android上获取图像的文件路径

答案:

发布到Twitter时,需要在发布请求中发送图片在设备上的实际路径。我发现很难找到实际的路径,而且经常会发现错误的路径。

为了解决这个问题,一旦有了a Bitmap,我就可以使用来获取URI getImageUri()。随后,我使用tempUriUri实例获取设备上的实际路径。

这是生产代码,并且经过了自然测试。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
        Bitmap photo = (Bitmap) data.getExtras().get("data"); 
        imageView.setImageBitmap(photo);
        knop.setVisibility(Button.VISIBLE);


        // CALL THIS METHOD TO GET THE URI FROM THE BITMAP
        Uri tempUri = getImageUri(getApplicationContext(), photo);

        // CALL THIS METHOD TO GET THE ACTUAL PATH
        File finalFile = new File(getRealPathFromURI(tempUri));

        System.out.println(mImageCaptureUri);
    }  
}

public Uri getImageUri(Context inContext, Bitmap inImage) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}

public String getRealPathFromURI(Uri uri) {
    Cursor cursor = getContentResolver().query(uri, null, null, null, null); 
    cursor.moveToFirst(); 
    int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
    return cursor.getString(idx); 
}

137、Windows 7上的Android Studio安装失败,未找到JDK

答案:

添加JDK_HOME具有值的系统变量c:\Program Files\Java\jdk1.7.0_21\对我有用。最新的Java版本可在此处下载。

此外,确保变量JAVA_HOME也设置在上述位置。

138、如何在Android中使用自定义按钮实现自定义操作栏?

答案:

如果要使用ActionBarAPI,这几乎与你将获得的接近。我不确定你是否可以在ActionBar不进行奇怪的Window黑客操作的情况下在其上方放置一个色带,这是不值得的。至于更改MenuItems流程,你可以通过样式使这些内容更紧密。可能会是这样,但我尚未对其进行测试。




这是如何向你的中添加自定义布局并将其添加到的方法ActionBar。

    // Inflate your custom layout
    final ViewGroup actionBarLayout = (ViewGroup) getLayoutInflater().inflate(
            R.layout.action_bar,
            null);

    // Set up your ActionBar
    final ActionBar actionBar = getActionBar();
    actionBar.setDisplayShowHomeEnabled(false);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setDisplayShowCustomEnabled(true);
    actionBar.setCustomView(actionBarLayout);

    // You customization
    final int actionBarColor = getResources().getColor(R.color.action_bar);
    actionBar.setBackgroundDrawable(new ColorDrawable(actionBarColor));

    final Button actionBarTitle = (Button) findViewById(R.id.action_bar_title);
    actionBarTitle.setText("Index(2)");

    final Button actionBarSent = (Button) findViewById(R.id.action_bar_sent);
    actionBarSent.setText("Sent");

    final Button actionBarStaff = (Button) findViewById(R.id.action_bar_staff);
    actionBarStaff.setText("Staff");

    final Button actionBarLocations = (Button) findViewById(R.id.action_bar_locations);
    actionBarLocations.setText("HIPPA Locations");

这是自定义布局:



    

这是色带布局:要使用它,只需使用merge你在其中充气的任何布局setContentView。


以下是Button样式:






这是我使用的颜色和尺寸:

#ff0d0d0d
#ffffffff
#99ffffff


14.0sp
16.0sp


5dp

如果你想对它进行更多自定义,则可以考虑完全不使用ActionBar,但我不建议这样做。你也可以考虑阅读《Android设计指南》,以更好地了解如何设计自己的ActionBar.

如果你选择放弃ActionBar并使用自己的布局,那么Toasts当用户长按“ MenuItems”时,应确保添加可操作的内容。使用此Gist可以轻松实现。

139、android asynctask发送回调到ui

答案:

您可以创建一个interface,将其传递给AsyncTask(在构造函数中),然后在中调用methodonPostExecute()

例如:

您的界面:

public interface OnTaskCompleted{
    void onTaskCompleted();
}

您的活动:

public class YourActivity implements OnTaskCompleted{
    // your Activity
}

和您的AsyncTask:

public class YourTask extends AsyncTask{ //change Object to required type
    private OnTaskCompleted listener;

    public YourTask(OnTaskCompleted listener){
        this.listener=listener;
    }

    // required methods

    protected void onPostExecute(Object o){
        // your stuff
        listener.onTaskCompleted();
    }
}

编辑

由于此答案非常受欢迎,因此我想补充一些内容。

如果您是Android开发的新手,那么这AsyncTask是一种在不阻止UI线程的情况下正常运行的快速方法。它确实确实解决了一些问题,但类本身的工作方式并没有错。但是,它带来了一些影响,例如:

内存泄漏的可能性。如果您继续参考Activity,即使用户离开屏幕(或旋转设备),它也将保留在内存中。
AsyncTask无法将结果传递给Activity是否Activity已被破坏。您必须添加额外的代码来管理所有这些内容,或者您​​要进行两次操作。
卷积的代码可以完成所有工作Activity
当您觉得自己已经足够成熟,可以继续使用Android时,请看一下这篇文章,我认为这是使用异步操作开发Android应用程序的更好方法。

140、如何在毕加索中使用磁盘缓存?

答案:

这就是我所做的。效果很好。

首先将OkHttp添加到app模块的gradle构建文件中:

compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.squareup.okhttp3:okhttp:3.10.0'
compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'

然后进行课堂扩展 Application

import android.app.Application;

import com.jakewharton.picasso.OkHttp3Downloader;
import com.squareup.picasso.Picasso;

public class Global extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        Picasso.Builder builder = new Picasso.Builder(this);
        builder.downloader(new OkHttp3Downloader(this,Integer.MAX_VALUE));
        Picasso built = builder.build();
        built.setIndicatorsEnabled(true);
        built.setLoggingEnabled(true);
        Picasso.setSingletonInstance(built);

    }
}

如下所示将其添加到清单文件中:




现在,像往常一样使用毕加索。没有变化。

编辑:

如果只想使用缓存的图像。这样调用库。我注意到,如果不添加networkPolicy,即使已缓存图像也不会在完全脱机的开始中显示。下面的代码解决了这个问题。

Picasso.with(this)
            .load(url)
            .networkPolicy(NetworkPolicy.OFFLINE)
            .into(imageView);

编辑#2

上面的代码的问题是,如果您清除缓存,毕加索将继续在缓存中脱机寻找它并失败,下面的代码示例将查看本地缓存,如果找不到离线,它将联机并补充缓存。

Picasso.with(getActivity())
.load(imageUrl)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(imageView, new Callback() {
    @Override
    public void onSuccess() {

    }

    @Override
    public void onError() {
        //Try again online if cache failed
        Picasso.with(getActivity())
                .load(posts.get(position).getImageUrl())
                .error(R.drawable.header)
                .into(imageView, new Callback() {
            @Override
            public void onSuccess() {

            }

            @Override
            public void onError() {
                Log.v("Picasso","Could not fetch image");
            }
        });
    }
});

结尾

今天的二十题安卓面试题就到此为止了,关注我,后续每日都会准时更新哦,喜欢的朋友不要吝啬你的赞和收藏哦,那我们明天再见!

你可能感兴趣的:(面试,android,android,studio,经验分享)