前言
写在前面:首先是不一次性放出来的原因:资料来之不易,希望大家好好珍惜,每天花一段时间细细的消化这些题目,其次希望大家在阅读题目的时候最好跟着书或者代码一起阅读、一起敲,做到熟稔于心,信手拈来,这样面试的时候才能展现你最自信的一面。
81、Android AsyncTask示例
答案:
好的,您正在尝试通过另一个线程访问GUI。基本上,这不是一个好习惯。
AsyncTask
在doInBackground()
另一个线程内部执行所有操作,该线程无法访问您的视图所在的GUI。
preExecute()
并postExecute()
在此新线程发生繁重之前和之后为您提供访问GUI的权限,甚至可以将long操作的结果传递给postExecute()
,然后显示任何处理结果。
请在以后更新TextView的地方查看这些行:
TextView txt = findViewById(R.id.output);
txt.setText("Executed");
把它们放进去onPostExecute()
。
doInBackground
完成后,您将看到更新的TextView文本。
我注意到您的onClick侦听器不会检查是否已选择哪个视图。我发现最简单的方法是通过switch语句。我在下面编辑了一个完整的课程,其中包含所有建议,以免造成混淆。
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class AsyncTaskActivity extends Activity implements OnClickListener {
Button btn;
AsyncTask<?, ?, ?> runningTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = findViewById(R.id.button1);
// Because we implement OnClickListener, we only
// have to pass "this" (much easier)
btn.setOnClickListener(this);
}
@Override
public void onClick(View view) {
// Detect the view that was "clicked"
switch (view.getId()) {
case R.id.button1:
if (runningTask != null)
runningTask.cancel(true);
runningTask = new LongOperation();
runningTask.execute();
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// Cancel running task(s) to avoid memory leaks
if (runningTask != null)
runningTask.cancel(true);
}
private final class LongOperation extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// We were cancelled; stop sleeping!
}
}
return "Executed";
}
@Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed"); // txt.setText(result);
// You might want to change "executed" for the returned string
// passed into onPostExecute(), but that is up to you
}
}
}
82、如何在Android中定义回调?
答案:
在许多情况下,您都有一个接口并传递实现该接口的对象。例如,对话框具有OnClickListener。
就像一个随机的例子:
// The callback interface
interface MyCallback {
void callbackCall();
}
// The class that takes the callback
class Worker {
MyCallback callback;
void onEvent() {
callback.callbackCall();
}
}
// Option 1:
class Callback implements MyCallback {
void callbackCall() {
// callback code goes here
}
}
worker.callback = new Callback();
// Option 2:
worker.callback = new MyCallback() {
void callbackCall() {
// callback code goes here
}
};
我可能弄乱了选项2中的语法。这还为时过早。
84、如何在Android中从位图裁剪圆形区域
答案:
经过长时间的头脑风暴,我找到了解决方案
public Bitmap getCroppedBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
bitmap.getWidth() / 2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
//Bitmap _bmp = Bitmap.createScaledBitmap(output, 60, 60, false);
//return _bmp;
return output;
}
85、从Android执行Shell命令
答案:
你应该获取su刚刚启动的进程的标准输入并在此处写下命令,否则你将使用current运行命令UID
。
尝试这样的事情:
try{
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
outputStream.writeBytes("screenrecord --time-limit 10 /sdcard/MyVideo.mp4\n");
outputStream.flush();
outputStream.writeBytes("exit\n");
outputStream.flush();
su.waitFor();
}catch(IOException e){
throw new Exception(e);
}catch(InterruptedException e){
throw new Exception(e);
}
87、Android中的单例与应用程序上下文?
答案:
我非常不同意Dianne Hackborn的回应。我们会逐步从项目中删除所有单例,以支持轻量级的,任务范围内的对象,可以在你实际需要它们时轻松地重新创建它们。
单例是测试的噩梦,如果延迟初始化,将引入“状态不确定性”,并带有微妙的副作用(当将调用getInstance()
从一个作用域移到另一个作用域时可能会突然浮出水面)。已经提到了可见性是另一个问题,并且由于单例意味着对共享状态的“全局”(=随机)访问,因此当在并发应用程序中未正确同步时,可能会出现细微的错误。
我认为这是一种反模式,这是一种糟糕的面向对象风格,从本质上讲相当于维持全局状态。
回到你的问题:
尽管应用程序上下文本身可以视为单例,但它是框架管理的,并且具有明确定义的生命周期,范围和访问路径。因此,我认为,如果你确实需要管理应用程序全局状态,则应该在这里,无处可去。对于其他任何事情,请重新考虑是否确实需要单例对象,或者是否有可能重写你的单例类以实例化执行手头任务的小型短期对象。
88、自定义字体和XML布局(Android)
答案:
TextViewPlus.java:
package com.example;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
public class TextViewPlus extends TextView {
private static final String TAG = "TextView";
public TextViewPlus(Context context) {
super(context);
}
public TextViewPlus(Context context, AttributeSet attrs) {
super(context, attrs);
setCustomFont(context, attrs);
}
public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setCustomFont(context, attrs);
}
private void setCustomFont(Context ctx, AttributeSet attrs) {
TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
String customFont = a.getString(R.styleable.TextViewPlus_customFont);
setCustomFont(ctx, customFont);
a.recycle();
}
public boolean setCustomFont(Context ctx, String asset) {
Typeface tf = null;
try {
tf = Typeface.createFromAsset(ctx.getAssets(), asset);
} catch (Exception e) {
Log.e(TAG, "Could not get typeface: "+e.getMessage());
return false;
}
setTypeface(tf